LALSimulation  5.4.0.1-c9a8ef6
burst.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2015 Jolien Creighton
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with with program; see the file COPYING. If not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 */
19 
20 /**
21  * @defgroup lalsim_burst lalsim-burst
22  * @ingroup lalsimulation_programs
23  *
24  * @brief Simulates a generic burst gravitational waveformS
25  *
26  * ### Synopsis
27  *
28  * lalsim-burst [options]
29  *
30  * ### Description
31  *
32  * The `lalsim-burst` utility produces a stream of a simulated gravitational
33  * waveform for a generic burst. The output data is the gravitational waveform
34  * polarizations in the time domain. The output is written to standard output
35  * as a three-column ascii format. The first column gives the time
36  * corresponding to each sample and the remaining columns give the
37  * gravitational waveform values for the two polarizations.
38  *
39  * ### Options
40  * [default values in brackets]
41  *
42  * <DL>
43  * <DT>`-h`, `--help`
44  * <DD>print a help message and exit</DD>
45  * <DT>`-v`, `--verbose`
46  * <DD>verbose output</DD>
47  * <DT>`-w` WAVEFM, `--waveform=WAVEFM`</DT>
48  * <DD>the waveform to generate</DD>
49  * <DT>`-t` DT, `--duration=DT`</DT>
50  * <DD>duration (seconds)</DD>
51  * <DT>`-f` FREQ, `--frequency=FREQ`</DT>
52  * <DD>frequency (Hz)</DD>
53  * <DT>`-b` BW, `--bandwidth=BW`</DT>
54  * <DD>bandwidth (Hz)</DD>
55  * <DT>`-q` Q, `--quality-factor=Q`</DT>
56  * <DD>quality factor (dimensionless)</DD>
57  * <DT>`-e` ECC, `--eccentricity=ECC`</DT>
58  * <DD>eccentricity 0<=ECC<=1 [0]</DD>
59  * <DT>`-p` PHI, `--phase=PHI`</DT>
60  * <DD>phase (degrees) [0]</DD>
61  * <DT>`-A` AMP, `--amplitude=AMP`</DT>
62  * <DD>amplitude (dimensionless or \f$ {\rm s}^{-1/3} \f$)</DD>
63  * <DT>`-H` HRSS, `--hrss=HRSS`</DT>
64  * <DD>root-sum-squared amplitude (\f$ {\rm Hz}^{-1/2} \f$)</DD>
65  * <DT>`-F` FLUENCE, `--fluence=`FLUENCE</DT>
66  * <DD>isotropic energy fluence (\f$ M_\odot c^2 / {\rm pc}^2 \f$)</DD>
67  * <DT>`-R` SRATE, --sample-rate=SRATE</DT>
68  * <DD>sample rate (Hz) [16384]</DD>
69  * </DL>
70  *
71  * ### Waveforms Supported
72  *
73  * <DL>
74  * <DT>BLTWNB</DT>
75  * <DD>band-limited white-noise burst<BR>
76  * required parameters: duration, frequency, bandwidth, eccentricity, fluence
77  * </DD>
78  * <DT>StringCusp</DT>
79  * <DD>cosmic string cusp<BR>
80  * required parameters: amplitude, frequency
81  * </DD>
82  * <DT>StringKink</DT>
83  * <DD>cosmic string kink<BR>
84  * required parameters: amplitude, frequency
85  * </DD>
86  * <DT>StringKinkKink</DT>
87  * <DD>cosmic string kink<BR>
88  * required parameters: amplitude
89  * </DD>
90  * <DT>SineGaussian</DT>
91  * <DD>cosine- or sine-Gaussian<BR>
92  * required parameters: quality-factor, frequency, hrss, eccentricity, phase
93  * </DD>
94  * <DT>Gaussian</DT>
95  * <DD>Gaussian<BR>
96  * required parameters: duration, hrss
97  * </DD>
98  * <DT>Impulse</DT>
99  * <DD>delta-function impulse<BR>
100  * required parameters: amplitude
101  * </DD>
102  * </DL>
103  *
104  * ### Environment
105  *
106  * The `LAL_DEBUG_LEVEL` can used to control the error and warning reporting of
107  * `lalsim-burst`. Common values are: `LAL_DEBUG_LEVEL=0` which suppresses
108  * error messages, `LAL_DEBUG_LEVEL=1` which prints error messages alone,
109  * `LAL_DEBUG_LEVEL=3` which prints both error messages and warning messages,
110  * and `LAL_DEBUG_LEVEL=7` which additionally prints informational messages.
111  *
112  * The `GSL_RNG_SEED` and `GSL_RNG_TYPE` environment variables can be used
113  * to set the random number generator seed and type respectively when
114  * generating band-limited white-noise bursts.
115  *
116  *
117  * ### Exit Status
118  *
119  * The `lalsim-burst` utility exits 0 on success, and >0 if an error occurs.
120  *
121  * ### Example
122  *
123  * The command:
124  *
125  * lalsim-burst --waveform BLTWNB --duration 0.1 --frequency 100 --bandwidth 100 --fluence 1e-14
126  *
127  * produces a three-column ascii output to standard output; the rows are
128  * samples (at the default rate of 16384 Hz), and the three columns are 1. the
129  * time of each sample, 2. the plus-polarization strain, and 3. the
130  * cross-polarization strain. The waveform produced is a band-limited
131  * white-noise burst with equal power in its two polarizations
132  * (eccentricity=0, which is the default value), a duration of 0.1 seconds,
133  * a frequency of 100 Hz, a bandwidth of 100 Hz, and a fluence of
134  * \f$ 10^{-14}\, M_\odot c^2 / {\rm pc}^2 = 0.01\, M_\odot c^2 / {\rm Mpc}^2
135  * \simeq 1.9\, {\rm J} / {\rm m}^2 \f$.
136  *
137  * The command:
138  *
139  * lalsim-burst -w SineGaussian -q 9 -e 1 -p 90 -f 150 -H 1e-22
140  *
141  * produces a Q=9 linearly polarized (since the eccentricity is set to 1)
142  * sine-Gaussian (not a cosine-Gaussian since the phase is set to 90 degrees)
143  * centered at 150 Hz having root-sum-squared strain
144  * \f$ h_{\mathrm{rss}} = 10^{-22}\, {\rm Hz}^{-1/2} \f$.
145  */
146 
147 #include <errno.h>
148 #include <math.h>
149 #include <stdlib.h>
150 #include <gsl/gsl_rng.h>
151 #include <lal/LALStdlib.h>
152 #include <lal/LALConstants.h>
153 #include <lal/LALgetopt.h>
154 #include <lal/Date.h>
155 #include <lal/TimeSeries.h>
156 #include <lal/LALSimBurst.h>
157 
158 #define XSTR(x) #x
159 #define STR(x) XSTR(x)
160 #define INVALID_DOUBLE (nan(""))
161 #define IS_INVALID_DOUBLE(x) (isnan(x))
162 #define DEFAULT_ECCENTRICITY 0 /* circularly polarized / unpolarized */
163 #define DEFAULT_PHASE 0 /* cosine phase */
164 #define DEFAULT_SRATE 16384
165 
166 static int verbose = 0;
167 #define verbose_output(...) (verbose ? fprintf(stderr, __VA_ARGS__) : 0)
168 
169 static int waveform_value(const char *waveform);
170 static double my_atof(const char *s);
171 static int output(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross);
172 static int usage(const char *program);
173 static struct params parseargs(int argc, char **argv);
174 
175 typedef enum {
185 
186 #define INIT_NAME(a) [a] = #a
187 static const char *waveform_names[NumWaveforms] = {
188  INIT_NAME(BLTWNB),
195 };
196 #undef INIT_NAME
197 
198 static const char *waveform_long_names[NumWaveforms] = {
199  [BLTWNB] = "band-limited white-noise burst",
200  [StringCusp] = "cosmic string cusp",
201  [StringKink] = "cosmic string kink",
202  [StringKinkKink] = "cosmic string kinkkink",
203  [SineGaussian] = "cosine- or sine-Gaussian",
204  [Gaussian] = "Gaussian",
205  [Impulse] = "delta-function impulse"
206 };
207 
208 static const char *waveform_parameters[NumWaveforms] = {
209  [BLTWNB] = "duration, frequency, bandwidth, eccentricity, phase, fluence",
210  [StringCusp] = "amplitude, frequency",
211  [StringKink] = "amplitude, frequency",
212  [StringKinkKink] = "amplitude",
213  [SineGaussian] = "quality-factor, frequency, hrss, eccentricity, phase",
214  [Gaussian] = "duration, hrss",
215  [Impulse] = "amplitude"
216 };
217 
218 static int waveform_value(const char *waveform)
219 {
220  int i;
221  for (i = 0; i < NumWaveforms; ++i)
222  if (strcmp(waveform, waveform_names[i]) == 0)
223  return i;
224  fprintf(stderr, "error: waveform `%s' not recognized\n", waveform);
225  return -1;
226 }
227 
228 /* like atof but prints an error message and returns NaN if an error occurs */
229 static double my_atof(const char *s)
230 {
231  int save_errno = errno;
232  char *endptr;
233  double val;
234  errno = 0;
235  val = strtod(s, &endptr);
236  if (errno != 0 || *endptr != '\0') {
237  save_errno = errno;
238  fprintf(stderr, "error: could not parse string `%s' into a double\n", s);
239  val = INVALID_DOUBLE;
240  }
241  errno = save_errno;
242  return val;
243 }
244 
245 struct params {
246  int waveform;
247  double duration;
248  double frequency;
249  double bandwidth;
250  double q;
251  double phase;
252  double eccentricity;
253  double amplitude;
254  double hrss;
255  double fluence;
256  double srate;
257 };
258 
259 int main(int argc, char **argv)
260 {
261  REAL8TimeSeries *hplus = NULL;
262  REAL8TimeSeries *hcross = NULL;
263  struct params p;
264  int status = 0;
265  gsl_rng *rng = NULL;
266 
268 
269  p = parseargs(argc, argv);
270 
271  if ((int)(p.waveform) < 0 || (int)(p.waveform) >= NumWaveforms) {
272  fprintf(stderr, "error: must specify valid waveform\n");
273  exit(1);
274  }
275 
276  if (p.waveform == BLTWNB) { /* set up gsl random number generator */
277  gsl_rng_env_setup();
278  rng = gsl_rng_alloc(gsl_rng_default);
279  }
280 
281  if (IS_INVALID_DOUBLE(p.srate) || p.srate <= 0.0) {
282  fprintf(stderr, "error: must specify valid sample rate\n");
283  status = 1;
284  }
285 
286  verbose_output("Input parameters:\n");
287  verbose_output("%-31s `%s' - %s\n", "waveform:", waveform_names[p.waveform], waveform_long_names[p.waveform]);
288  verbose_output("%-31s %g (Hz)\n", "sample rate:", p.srate);
289 
290  switch (p.waveform) {
291 
292  case BLTWNB:
293 
294  /* sanity check relevant parameters */
295  if (IS_INVALID_DOUBLE(p.duration) || p.duration < 0.0) {
296  fprintf(stderr, "error: must specify valid duration for waveform `%s'\n", waveform_names[p.waveform]);
297  status = 1;
298  }
299  if (IS_INVALID_DOUBLE(p.frequency) || p.frequency < 0.0) {
300  fprintf(stderr, "error: must specify valid frequency for waveform `%s'\n", waveform_names[p.waveform]);
301  status = 1;
302  }
303  if (IS_INVALID_DOUBLE(p.bandwidth) || p.bandwidth < 0.0) {
304  fprintf(stderr, "error: must specify valid bandwidth for waveform `%s'\n", waveform_names[p.waveform]);
305  status = 1;
306  }
307  if (IS_INVALID_DOUBLE(p.eccentricity) || p.eccentricity < 0.0 || p.eccentricity > 1.0) {
308  fprintf(stderr, "error: must specify valid eccentricity in domain [0,1] for waveform `%s'\n", waveform_names[p.waveform]);
309  status = 1;
310  }
311  if (IS_INVALID_DOUBLE(p.phase)) {
312  fprintf(stderr, "error: must specify valid phase for waveform `%s'\n", waveform_names[p.waveform]);
313  status = 1;
314  }
315  if (IS_INVALID_DOUBLE(p.fluence) || p.fluence < 0.0) {
316  fprintf(stderr, "error: must specify valid fluence for waveform `%s'\n", waveform_names[p.waveform]);
317  status = 1;
318  }
319 
320  /* detect set but ignored parameters */
321  if (!IS_INVALID_DOUBLE(p.q))
322  fprintf(stderr, "warning: quality-factor parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
323  if (p.phase != DEFAULT_PHASE)
324  fprintf(stderr, "warning: phase parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
325  if (!IS_INVALID_DOUBLE(p.amplitude))
326  fprintf(stderr, "warning: amplitude parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
327  if (!IS_INVALID_DOUBLE(p.hrss))
328  fprintf(stderr, "warning: hrss parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
329 
330  if (!status) {
331  double int_hdot_squared_dt;
332  int_hdot_squared_dt = p.fluence * LAL_GMSUN_SI * 4 / LAL_C_SI / LAL_PC_SI / LAL_PC_SI;
333 
334  verbose_output("%-31s %g (s)\n", "duration:", p.duration);
335  verbose_output("%-31s %g (Hz)\n", "frequency:", p.frequency);
336  verbose_output("%-31s %g (Hz)\n", "bandwidth:", p.bandwidth);
337  verbose_output("%-31s %g\n", "eccentricity:", p.eccentricity);
338  verbose_output("%-31s %g (Msun c^2 pc^-2)\n", "fluence:", p.fluence);
339  verbose_output("%-31s %g (s^-1)\n", "integral (dh/dt)^2 dt:", int_hdot_squared_dt);
340  verbose_output("%-31s GSL_RNG_TYPE=%s\n", "GSL random number generator:", gsl_rng_name(rng));
341  verbose_output("%-31s GSL_RNG_SEED=%lu\n", "GSL random number seed:", gsl_rng_default_seed);
342  status = XLALGenerateBandAndTimeLimitedWhiteNoiseBurst(&hplus, &hcross, p.duration, p.frequency, p.bandwidth, p.eccentricity, p.phase, int_hdot_squared_dt, 1.0/p.srate, rng);
343  }
344  break;
345 
346  case StringCusp:
347 
348  /* sanity check relevant parameters */
349  if (IS_INVALID_DOUBLE(p.amplitude) || p.amplitude < 0.0) {
350  fprintf(stderr, "error: must specify valid amplitude for waveform `%s'\n", waveform_names[p.waveform]);
351  status = 1;
352  }
353  if (IS_INVALID_DOUBLE(p.frequency) || p.frequency < 0.0) {
354  fprintf(stderr, "error: must specify valid frequency for waveform `%s'\n", waveform_names[p.waveform]);
355  status = 1;
356  }
357 
358  /* detect set but ignored parameters */
359  if (!IS_INVALID_DOUBLE(p.duration))
360  fprintf(stderr, "warning: duration parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
361  if (!IS_INVALID_DOUBLE(p.bandwidth))
362  fprintf(stderr, "warning: bandwidth parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
363  if (!IS_INVALID_DOUBLE(p.q))
364  fprintf(stderr, "warning: quality-factor parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
365  if (p.eccentricity != DEFAULT_ECCENTRICITY)
366  fprintf(stderr, "warning: eccentricity parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
367  if (p.phase != DEFAULT_PHASE)
368  fprintf(stderr, "warning: phase parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
369  if (!IS_INVALID_DOUBLE(p.hrss))
370  fprintf(stderr, "warning: hrss parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
371  if (!IS_INVALID_DOUBLE(p.fluence))
372  fprintf(stderr, "warning: fluence parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
373 
374  if (!status) {
375  verbose_output("%-31s %g (s^-1/3)\n", "amplitude:", p.amplitude);
376  verbose_output("%-31s %g (Hz)\n", "frequency:", p.frequency);
377  status = XLALGenerateStringCusp(&hplus, &hcross, p.amplitude, p.frequency, 1.0/p.srate);
378  }
379  break;
380 
381  case StringKink:
382 
383  /* sanity check relevant parameters */
384  if (IS_INVALID_DOUBLE(p.amplitude) || p.amplitude < 0.0) {
385  fprintf(stderr, "error: must specify valid amplitude for waveform `%s'\n", waveform_names[p.waveform]);
386  status = 1;
387  }
388  if (IS_INVALID_DOUBLE(p.frequency) || p.frequency < 0.0) {
389  fprintf(stderr, "error: must specify valid frequency for waveform `%s'\n", waveform_names[p.waveform]);
390  status = 1;
391  }
392 
393  /* detect set but ignored parameters */
394  if (!IS_INVALID_DOUBLE(p.duration))
395  fprintf(stderr, "warning: duration parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
396  if (!IS_INVALID_DOUBLE(p.bandwidth))
397  fprintf(stderr, "warning: bandwidth parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
398  if (!IS_INVALID_DOUBLE(p.q))
399  fprintf(stderr, "warning: quality-factor parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
400  if (p.eccentricity != DEFAULT_ECCENTRICITY)
401  fprintf(stderr, "warning: eccentricity parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
402  if (p.phase != DEFAULT_PHASE)
403  fprintf(stderr, "warning: phase parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
404  if (!IS_INVALID_DOUBLE(p.hrss))
405  fprintf(stderr, "warning: hrss parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
406  if (!IS_INVALID_DOUBLE(p.fluence))
407  fprintf(stderr, "warning: fluence parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
408 
409  if (!status) {
410  verbose_output("%-31s %g (s^-2/3)\n", "amplitude:", p.amplitude);
411  verbose_output("%-31s %g (Hz)\n", "frequency:", p.frequency);
412  status = XLALGenerateStringKink(&hplus, &hcross, p.amplitude, p.frequency, 1.0/p.srate);
413  }
414  break;
415 
416  case StringKinkKink:
417 
418  /* sanity check relevant parameters */
419  if (IS_INVALID_DOUBLE(p.amplitude) || p.amplitude < 0.0) {
420  fprintf(stderr, "error: must specify valid amplitude for waveform `%s'\n", waveform_names[p.waveform]);
421  status = 1;
422  }
423 
424  /* detect set but ignored parameters */
425  if (!IS_INVALID_DOUBLE(p.frequency))
426  fprintf(stderr, "warning: frequency parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
427  if (!IS_INVALID_DOUBLE(p.duration))
428  fprintf(stderr, "warning: duration parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
429  if (!IS_INVALID_DOUBLE(p.bandwidth))
430  fprintf(stderr, "warning: bandwidth parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
431  if (!IS_INVALID_DOUBLE(p.q))
432  fprintf(stderr, "warning: quality-factor parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
433  if (p.eccentricity != DEFAULT_ECCENTRICITY)
434  fprintf(stderr, "warning: eccentricity parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
435  if (p.phase != DEFAULT_PHASE)
436  fprintf(stderr, "warning: phase parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
437  if (!IS_INVALID_DOUBLE(p.hrss))
438  fprintf(stderr, "warning: hrss parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
439  if (!IS_INVALID_DOUBLE(p.fluence))
440  fprintf(stderr, "warning: fluence parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
441 
442  if (!status) {
443  verbose_output("%-31s %g (s^-1)\n", "amplitude:", p.amplitude);
444  status = XLALGenerateStringKinkKink(&hplus, &hcross, p.amplitude, 1.0/p.srate);
445  }
446  break;
447 
448  case SineGaussian:
449 
450  /* sanity check relevant parameters */
451  if (IS_INVALID_DOUBLE(p.q) || p.q < 0.0) {
452  fprintf(stderr, "error: must specify valid quality factor for waveform `%s'\n", waveform_names[p.waveform]);
453  status = 1;
454  }
455  if (IS_INVALID_DOUBLE(p.frequency) || p.frequency < 0.0) {
456  fprintf(stderr, "error: must specify valid frequency for waveform `%s'\n", waveform_names[p.waveform]);
457  status = 1;
458  }
459  if (IS_INVALID_DOUBLE(p.hrss) || p.hrss < 0.0) {
460  fprintf(stderr, "error: must specify valid hrss for waveform `%s\n", waveform_names[p.waveform]);
461  status = 1;
462  }
463  if (IS_INVALID_DOUBLE(p.eccentricity) || p.eccentricity < 0.0 || p.eccentricity > 1.0) {
464  fprintf(stderr, "error: must specify valid eccentricity in domain [0,1] for waveform `%s'\n", waveform_names[p.waveform]);
465  status = 1;
466  }
467  if (IS_INVALID_DOUBLE(p.phase)) {
468  fprintf(stderr, "error: must specify valid phase for waveform `%s'\n", waveform_names[p.waveform]);
469  status = 1;
470  }
471 
472  /* detect set but ignored parameters */
473  if (!IS_INVALID_DOUBLE(p.duration))
474  fprintf(stderr, "warning: duration parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
475  if (!IS_INVALID_DOUBLE(p.bandwidth))
476  fprintf(stderr, "warning: bandwidth parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
477  if (!IS_INVALID_DOUBLE(p.amplitude))
478  fprintf(stderr, "warning: amplitude parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
479  if (!IS_INVALID_DOUBLE(p.fluence))
480  fprintf(stderr, "warning: fluence parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
481 
482  if (!status) {
483  verbose_output("%-31s %g\n", "quality-factor:", p.q);
484  verbose_output("%-31s %g (Hz)\n", "frequency:", p.frequency);
485  verbose_output("%-31s %g (Hz^-1/2)\n", "root-sum-squared strain:", p.hrss);
486  verbose_output("%-31s %g\n", "eccentricity:", p.eccentricity);
487  verbose_output("%-31s %g (degrees)\n", "phase:", p.phase / LAL_PI_180);
488  status = XLALSimBurstSineGaussian(&hplus, &hcross, p.q, p.frequency, p.hrss, p.eccentricity, p.phase, 1.0/p.srate);
489  }
490  break;
491 
492  case Gaussian:
493 
494  /* sanity check relevant parameters */
495  if (IS_INVALID_DOUBLE(p.duration) || p.duration < 0.0) {
496  fprintf(stderr, "error: must specify valid duration for waveform `%s'\n", waveform_names[p.waveform]);
497  status = 1;
498  }
499  if (IS_INVALID_DOUBLE(p.hrss) || p.hrss < 0.0) {
500  fprintf(stderr, "error: must specify valid hrss for waveform `%s'\n", waveform_names[p.waveform]);
501  status = 1;
502  }
503  /* detect set but ignored parameters */
504  if (!IS_INVALID_DOUBLE(p.frequency))
505  fprintf(stderr, "warning: frequency parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
506  if (!IS_INVALID_DOUBLE(p.bandwidth))
507  fprintf(stderr, "warning: bandwidth parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
508  if (!IS_INVALID_DOUBLE(p.q))
509  fprintf(stderr, "warning: quality-factor parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
510  if (p.eccentricity != DEFAULT_ECCENTRICITY)
511  fprintf(stderr, "warning: eccentricity parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
512  if (p.phase != DEFAULT_PHASE)
513  fprintf(stderr, "warning: phase parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
514  if (!IS_INVALID_DOUBLE(p.amplitude))
515  fprintf(stderr, "warning: amplitude parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
516  if (!IS_INVALID_DOUBLE(p.fluence))
517  fprintf(stderr, "warning: fluence parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
518  if (!status) {
519  verbose_output("%-31s %g (s)\n", "duration:", p.duration);
520  verbose_output("%-31s %g (Hz^-1/2)\n", "root-sum-squared strain:", p.hrss);
521  status = XLALSimBurstGaussian(&hplus, &hcross, p.duration, p.hrss, 1.0/p.srate);
522  }
523 
524  break;
525 
526  case Impulse:
527 
528  /* sanity check relevant parameters */
529  if (IS_INVALID_DOUBLE(p.amplitude) || p.amplitude < 0.0) {
530  fprintf(stderr, "error: must specify valid amplitude for waveform `%s'\n", waveform_names[p.waveform]);
531  status = 1;
532  }
533 
534  /* detect set but ignored parameters */
535  if (!IS_INVALID_DOUBLE(p.duration))
536  fprintf(stderr, "warning: duration parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
537  if (!IS_INVALID_DOUBLE(p.frequency))
538  fprintf(stderr, "warning: frequency parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
539  if (!IS_INVALID_DOUBLE(p.bandwidth))
540  fprintf(stderr, "warning: bandwidth parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
541  if (!IS_INVALID_DOUBLE(p.q))
542  fprintf(stderr, "warning: quality-factor parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
543  if (p.eccentricity != DEFAULT_ECCENTRICITY)
544  fprintf(stderr, "warning: eccentricity parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
545  if (p.phase != DEFAULT_PHASE)
546  fprintf(stderr, "warning: phase parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
547  if (!IS_INVALID_DOUBLE(p.hrss))
548  fprintf(stderr, "warning: hrss parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
549  if (!IS_INVALID_DOUBLE(p.fluence))
550  fprintf(stderr, "warning: fluence parameter is set but ignored for waveform `%s'\n", waveform_names[p.waveform]);
551 
552  if (!status) {
553  verbose_output("%-31s %g (dimensionless)\n", "amplitude:", p.amplitude);
554  status = XLALGenerateImpulseBurst(&hplus, &hcross, p.amplitude, 1.0/p.srate);
555  }
556  break;
557 
558  default:
559  fprintf(stderr, "error: unrecognized waveform\n");
560  exit(1);
561  };
562 
563  if (status)
564  exit(1);
565 
566  if (verbose) {
567  char peak_time[32]; // GPS time string - 31 characters is enough
568  LIGOTimeGPS tpeak;
569  COMPLEX16 hpeak;
570  double hrss;
571  double fluence;
572  unsigned ipeak;
573  hpeak = XLALMeasureHPeak(hplus, hcross, &ipeak);
574  tpeak = hplus->epoch;
575  XLALGPSAdd(&tpeak, ipeak * hplus->deltaT);
576  XLALGPSToStr(peak_time, &tpeak);
577  hrss = XLALMeasureHrss(hplus, hcross);
578  fluence = XLALMeasureEoverRsquared(hplus, hcross);
579  verbose_output("Measured parameters:\n");
580  verbose_output("%-31s %s (s)\n", "peak time:", peak_time);
581  verbose_output("%-31s (h+, hx) = (%g, %g)\n", "peak strain amplitude:", creal(hpeak), cimag(hpeak));
582  verbose_output("%-31s abs(h+, hx) = %g\n", "peak strain amplitude:", cabs(hpeak));
583  verbose_output("%-31s arg(h+, hx) = %g (rad)\n", "peak strain amplitude:", carg(hpeak));
584  verbose_output("%-31s %g (Hz^-1/2)\n", "root-sum-squared strain:", hrss);
585  verbose_output("%-31s %g (J m^-2)\n", "isotropic energy fluence:", fluence);
586  verbose_output("%-31s %g (Msun c^2 pc^-2)\n", "isotropic energy fluence:", fluence * LAL_PC_SI * LAL_PC_SI / LAL_MSUN_SI / LAL_C_SI / LAL_C_SI);
587  }
588 
589  output(hplus, hcross);
590 
594  return 0;
595 }
596 
597 static int output(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross)
598 {
599  char tstr[32]; // GPS time string - 31 characters is enough
600  size_t j;
601  fprintf(stdout, "# time (s)\tH_PLUS (strain)\tH_CROSS (strain)\n");
602  for (j = 0; j < hplus->data->length; ++j) {
603  LIGOTimeGPS t = hplus->epoch;
604  fprintf(stdout, "%s\t%.18e\t%.18e\n", XLALGPSToStr(tstr, XLALGPSAdd(&t, j * hplus->deltaT)), hplus->data->data[j], hcross->data->data[j]);
605  }
606  return 0;
607 }
608 
609 static int usage(const char *program)
610 {
611  int i;
612  const char *options =
613 /* *INDENT-OFF* */
614 "[default values in brackets]\n"
615 " -h, --help print this message and exit\n"
616 " -v, --verbose verbose output\n"
617 " -w WAVEFM, --waveform=WAVEFM the waveform to generate\n"
618 " -t DT, --duration=DT duration (seconds)\n"
619 " -f FREQ, --frequency=FREQ frequency (Hz)\n"
620 " -b BW, --bandwidth=BW bandwidth (Hz)\n"
621 " -q Q, --quality-factor=Q quality factor (dimensionless)\n"
622 " -e ECC, --eccentricity=ECC eccentricity 0<=ECC<=1 [" STR(DEFAULT_ECCENTRICITY) "]\n"
623 " -p PHI, --phase=PHI phase (degrees) [" STR(DEFAULT_PHASE) "]\n"
624 " -A AMP, --amplitude=AMP amplitude (dimensionless or s^-1/3)\n"
625 " -H HRSS, --hrss=HRSS root-sum-squared amplitude (Hz^-1/2)\n"
626 " -F FLUENCE, --fluence=FLUENCE isotropic energy fluence (Msun c^2 pc^-2)\n"
627 " -R SRATE, --sample-rate=SRATE sample rate (Hz) [" STR(DEFAULT_SRATE) "]\n";
628 /* *INDENT-ON* */
629  fprintf(stderr, "usage: %s [options]\n", program);
630  fprintf(stderr, "options:\n%s\n", options);
631  fprintf(stderr, "waveforms supported:\n");
632  for (i = 0; i < NumWaveforms; ++i) {
633  fprintf(stderr, "\n\t`%s' - %s\n", waveform_names[i], waveform_long_names[i]);
634  fprintf(stderr, "\t\trequires: %s\n", waveform_parameters[i]);
635  }
636  return 0;
637 }
638 
639 static struct params parseargs(int argc, char **argv)
640 {
641  struct params p = {
642  .waveform = -1, /* invalid */
643  .duration = INVALID_DOUBLE, /* invalid */
644  .frequency = INVALID_DOUBLE, /* invalid */
645  .bandwidth = INVALID_DOUBLE, /* invalid */
646  .q = INVALID_DOUBLE, /* invalid */
647  .phase = DEFAULT_PHASE,
648  .eccentricity = DEFAULT_ECCENTRICITY,
649  .amplitude = INVALID_DOUBLE, /* invalid */
650  .hrss = INVALID_DOUBLE, /* invalid */
651  .fluence = INVALID_DOUBLE, /* invalid */
652  .srate = DEFAULT_SRATE
653  };
654  struct LALoption long_options[] = {
655  {"help", no_argument, 0, 'h'},
656  {"verbose", no_argument, 0, 'v'},
657  {"waveform", required_argument, 0, 'w'},
658  {"duration", required_argument, 0, 't'},
659  {"frequency", required_argument, 0, 'f'},
660  {"bandwidth", required_argument, 0, 'b'},
661  {"quality-factor", required_argument, 0, 'q'},
662  {"eccentricity", required_argument, 0, 'e'},
663  {"phase", required_argument, 0, 'p'},
664  {"amplitude", required_argument, 0, 'A'},
665  {"hrss", required_argument, 0, 'H'},
666  {"fluence", required_argument, 0, 'F'},
667  {"sample-rate", required_argument, 0, 'R'},
668  {0, 0, 0, 0}
669  };
670  char args[] = "hvw:t:f:b:q:e:A:H:F:d:R:";
671 
672  while (1) {
673  int option_index = 0;
674  int c;
675 
676  c = LALgetopt_long_only(argc, argv, args, long_options, &option_index);
677  if (c == -1) /* end of options */
678  break;
679 
680  switch (c) {
681  case 0: /* if option set a flag, nothing else to do */
682  if (long_options[option_index].flag)
683  break;
684  else {
685  fprintf(stderr, "error parsing option %s with argument %s\n", long_options[option_index].name, LALoptarg);
686  exit(1);
687  }
688  case 'h': /* help */
689  usage(argv[0]);
690  exit(0);
691  case 'v': /* verbose */
692  verbose = 1;
693  break;
694  case 'w': /* waveform */
695  p.waveform = waveform_value(LALoptarg);
696  break;
697  case 't': /* duration */
698  p.duration = my_atof(LALoptarg);
699  break;
700  case 'f': /* frequency */
701  p.frequency = my_atof(LALoptarg);
702  break;
703  case 'b': /* bandwidth */
704  p.bandwidth = my_atof(LALoptarg);
705  break;
706  case 'q': /* quality-factor */
707  p.q = my_atof(LALoptarg);
708  break;
709  case 'e': /* eccentricity */
710  p.eccentricity = my_atof(LALoptarg);
711  break;
712  case 'p': /* phase */
713  /* convert phase from degrees to radians */
714  p.phase = my_atof(LALoptarg) * LAL_PI_180;
715  break;
716  case 'A': /* amplitude */
717  p.amplitude = my_atof(LALoptarg);
718  break;
719  case 'H': /* hrss */
720  p.hrss = my_atof(LALoptarg);
721  break;
722  case 'F': /* fluence */
723  /* convert fluence to sum-squared hdot */
724  p.fluence = my_atof(LALoptarg);
725  break;
726  case 'R': /* sample-rate */
727  p.srate = my_atof(LALoptarg);
728  break;
729  case '?':
730  default:
731  fprintf(stderr, "unknown error while parsing options\n");
732  exit(1);
733  }
734  }
735  if (LALoptind < argc) {
736  fprintf(stderr, "extraneous command line arguments:\n");
737  while (LALoptind < argc)
738  fprintf(stderr, "%s\n", argv[LALoptind++]);
739  exit(1);
740  }
741  return p;
742 }
void LALCheckMemoryLeaks(void)
#define c
const char * name
#define char
Definition: LALSimUnicorn.c:14
int LALgetopt_long_only(int argc, char *const *argv, const char *options, const struct LALoption *long_options, int *opt_index)
#define no_argument
#define required_argument
#define fprintf
int s
Definition: bh_qnmode.c:137
double i
Definition: bh_ringdown.c:118
static int verbose
Definition: burst.c:166
#define STR(x)
Definition: burst.c:159
static int waveform_value(const char *waveform)
Definition: burst.c:218
static int output(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross)
Definition: burst.c:597
#define DEFAULT_SRATE
Definition: burst.c:164
int main(int argc, char **argv)
Definition: burst.c:259
static struct params parseargs(int argc, char **argv)
Definition: burst.c:639
static const char * waveform_long_names[NumWaveforms]
Definition: burst.c:198
#define INIT_NAME(a)
Definition: burst.c:186
static double my_atof(const char *s)
Definition: burst.c:229
waveform_enum
Definition: burst.c:175
@ StringKinkKink
Definition: burst.c:179
@ StringKink
Definition: burst.c:178
@ NumWaveforms
Definition: burst.c:183
@ BLTWNB
Definition: burst.c:176
@ StringCusp
Definition: burst.c:177
@ Impulse
Definition: burst.c:182
@ Gaussian
Definition: burst.c:181
@ SineGaussian
Definition: burst.c:180
static const char * waveform_parameters[NumWaveforms]
Definition: burst.c:208
static const char * waveform_names[NumWaveforms]
Definition: burst.c:187
#define DEFAULT_PHASE
Definition: burst.c:163
#define INVALID_DOUBLE
Definition: burst.c:160
static int usage(const char *program)
Definition: burst.c:609
#define DEFAULT_ECCENTRICITY
Definition: burst.c:162
#define verbose_output(...)
Definition: burst.c:167
#define IS_INVALID_DOUBLE(x)
Definition: burst.c:161
char * XLALGPSToStr(char *s, const LIGOTimeGPS *t)
#define LAL_C_SI
#define LAL_MSUN_SI
#define LAL_PI_180
#define LAL_GMSUN_SI
#define LAL_PC_SI
double complex COMPLEX16
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
int XLALGenerateStringKinkKink(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 amplitude, REAL8 delta_t)
Generates cosmic string kink waveforms.
Definition: LALSimBurst.c:1619
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
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
int XLALGenerateStringCusp(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 amplitude, REAL8 f_high, REAL8 delta_t)
Generates cosmic string cusp waveforms.
Definition: LALSimBurst.c:1520
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
void XLALAbortErrorHandler(const char *func, const char *file, int line, int errnum)
XLALErrorHandlerType * XLALSetErrorHandler(XLALErrorHandlerType *newHandler)
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
char * program
Definition: inject.c:87
list p
string status
def options
int * flag
REAL8Sequence * data
LIGOTimeGPS epoch
REAL8 * data
Definition: burst.c:245
double srate
Definition: burst.c:256
double frequency
Definition: burst.c:248
double amplitude
Definition: burst.c:253
double bandwidth
Definition: burst.c:249
double eccentricity
Definition: burst.c:252
double duration
Definition: burst.c:247
double q
Definition: burst.c:250
double fluence
Definition: burst.c:255
double hrss
Definition: burst.c:254
int waveform
Definition: burst.c:246
double phase
Definition: burst.c:251
double hrss
Definition: unicorn.c:21