LALSimulation  5.4.0.1-89842e6
inspiral.c
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2014 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_inspiral lalsim-inspiral
22  * @ingroup lalsimulation_programs
23  *
24  * @brief Simulates a gravitational waveform from binary inspiral
25  *
26  * ### Synopsis
27  *
28  * lalsim-inspiral [options]
29  *
30  * ### Description
31  *
32  * The `lalsim-inspiral` utility produces a stream of a simulated
33  * gravitational waveform from a binary inspiral. The output data is
34  * the gravitational waveform polarizations in the time domain, or
35  * in the frequency domain if the `-F` option is specified. If the
36  * option `-Q` is specified, the output data is in amplitude and phase.
37  * This program uses XLALSimInspiralChooseTDWaveform() or
38  * XLALSimInspiralChooseFDWaveform() unless the `-c` waveform contitioning
39  * option is given, in which case it uses XLALSimInspiralTD() or
40  * XLALSimInspiralFD(). The output is written to standard output as a
41  * multicolumn ascii format. The first column gives the time or frequency
42  * corresponding to each sample and the remaining columns give the
43  * gravitational waveform values for the two polarizations (real and
44  * imaginary parts, or amplitude and phase when complex).
45  *
46  * ### Options
47  * [default values in brackets]
48  *
49  * <DL>
50  * <DT>`-h`, `--help`
51  * <DD>print a help message and exit</DD>
52  * <DT>`-v`, `--verbose`
53  * <DD>verbose output</DD>
54  * <DT>`-C`, `--radians`</DT>
55  * <DD>use radians rather than decimal degrees</DD>
56  * <DT>`-F`, `--frequency-domain`
57  * <DD>output data in frequency domain</DD>
58  * <DT>`-c`, `--condition-waveform`
59  * <DD>apply waveform conditioning</DD>
60  * <DT>`-P`, `--amp-phase`
61  * <DD>output data as amplitude and phase</DD>
62  * <DT>`-a` APPROX, `--approximant=`APPROX
63  * <DD>approximant [TaylorT1]</DD>
64  * <DT>`-w` WAVEFORM, `--waveform=`WAVEFORM
65  * <DD>waveform string giving both approximant and order</DD>
66  * <DT>`-D` domain, `--domain=`DOMAIN
67  * <DD>domain for waveform generation when both are available {"time", "freq"}
68  * [use natural domain for output]</DD>
69  * <DT>`-O` PHASEO, `--phase-order=`PHASEO
70  * <DD>twice pN order of phase (-1 == highest) [-1]</DD>
71  * <DT>`-o` AMPO, `--amp-order=`AMPO
72  * <DD>twice pN order of amplitude (-1 == highest) [0]</DD>
73  * <DT>`-u` PHIREF, `--phiRef=`PHIREF
74  * <DD>reference phase in degrees [0]</DD>
75  * <DT>`-U` PERIANOM, `--periastron-anomaly=`PERIANOM
76  * <DD>mean periastron anomaly in degrees [0]</DD>
77  * <DT>`-W` LONGASC, `--longitude-ascending-node=`LONGASC
78  * <DD>longitude of ascending node in degrees [0]</DD>
79  * <DT>`-e` ECC, `--eccentricity=`ECC
80  * <DD>orbital eccentricity [0]</DD>
81  * <DT>`-R` SRATE, `--sample-rate=`SRATE
82  * <DD>sample rate in Hertz [16384]</DD>
83  * <DT>`-M` M1, `--m1=`M1
84  * <DD>mass of primary in solar masses [1.4]</DD>
85  * <DT>`-m` M2, `--m2=`M2
86  * <DD>mass of secondary in solar masses [1.4]</DD>
87  * <DT>`-d` D, `--distance=`D
88  * <DD>distance in Mpc [1]</DD>
89  * <DT>`-i` IOTA, `--inclination=`IOTA
90  * <DD>inclination in degrees [0]</DD>
91  * <DT>`-X` S1X, `--spin1x=`S1X
92  * <DD>x-component of dimensionless spin of primary [0]</DD>
93  * <DT>`-Y` S1Y, `--spin1y=`S1Y
94  * <DD>y-component of dimensionless spin of primary [0]</DD>
95  * <DT>`-Z` S1Z, `--spin1z=`S1Z
96  * <DD>z-component of dimensionless spin of primary [0]</DD>
97  * <DT>`-x` S2X, `--spin2x=`S2X
98  * <DD>x-component of dimensionless spin of secondary [0]</DD>
99  * <DT>`-y` S2Y, `--spin2y=`S2Y
100  * <DD>y-component of dimensionless spin of secondary [0]</DD>
101  * <DT>`-z` S2Z, `--spin2z=`S2Z
102  * <DD>z-component of dimensionless spin of secondary [0]</DD>
103  * <DT>`-L` LAM1, `--tidal-lambda1=`LAM1
104  * <DD>dimensionless tidal deformability of primary [0]</DD>
105  * <DT>`-l` LAM2, `--tidal-lambda2=`LAM2
106  * <DD>dimensionless tidal deformability of secondary [0]</DD>
107  * <DT>`-q` DQM1, `--delta-quad-mon1=`DQM1
108  * <DD>difference in quadrupole-monopole term of primary [0]</DD>
109  * <DT>`-Q` DQM2, `--delta-quad-mon2=`DQM2
110  * <DD>difference in quadrupole-monopole term of secondary [0]</DD>
111  * <DT>`-s` SPINO, `--spin-order=`SPINO
112  * <DD>twice pN order of spin effects (-1 == all) [-1]</DD>
113  * <DT>`-t` TIDEO, `--tidal-order=`TIDEO
114  * <DD>twice pN order of tidal effects (-1 == all) [-1]</DD>
115  * <DT>`-f` FMIN, `--f-min=`FMIN
116  * <DD>frequency to start waveform in Hertz [40]</DD>
117  * <DT>`-r` FREF, `--fRef=`FREF
118  * <DD>reference frequency in Hertz [0]</DD>
119  * <DT>`-A` AXIS, `--axis=`AXIS
120  * <DD>axis for PhenSpin {View, TotalJ, OrbitalL} [OrbitalL]</DD>
121  * <DT>`-n` MODES, `--modes=`MODES
122  * <DD>allowed l modes {L2, L23, ..., ALL} [L2]</DD>
123  * <DT>`-p` KEY1`=`VAL1`,`KEY2`=`VAL2,...,
124  * `--params=`KEY1`=`VAL1`,`KEY2`=`VAL2,...</DT>
125  * <DD>extra parameters as a key-value pair</DD>
126  * </DL>
127  *
128  * ### Environment
129  *
130  * The `LAL_DEBUG_LEVEL` can used to control the error and warning reporting of
131  * `lalsim-inspiral`. Common values are: `LAL_DEBUG_LEVEL=0` which suppresses
132  * error messages, `LAL_DEBUG_LEVEL=1` which prints error messages alone,
133  * `LAL_DEBUG_LEVEL=3` which prints both error messages and warning messages,
134  * and `LAL_DEBUG_LEVEL=7` which additionally prints informational messages.
135  *
136  * ### Exit Status
137  *
138  * The `lalsim-inspiral` utility exits 0 on success, and >0 if an error occurs.
139  *
140  * ### Example
141  *
142  * The command:
143  *
144  * lalsim-inspiral --approx=TaylorT3
145  *
146  * produces a three-column ascii output to standard output; the rows are
147  * samples (at the default rate of 16384 Hz), and the three columns are 1. the
148  * time of each sample, 2. the plus-polarization strain, and 3. the
149  * cross-polarization strain. The waveform produced is for the TaylorT3
150  * post-Newtonian approximant for the default parameters of a 1.4 solar mass +
151  * 1.4 solar mass binary inspiral at 1 Mpc distance.
152  *
153  * The command:
154  *
155  * lalsim-inspiral --m1=10 --m2=10 --approx=TaylorF2 --frequency-domain
156  *
157  * produces a frequency-domain waveform for a 10 solar mass + 10 solar mass
158  * binary inspiral at 1 Mpc distance using the TaylorF2 approximant. The five
159  * columns written to standard output are the frequency of each sample, the
160  * real part of the plus-polarization, the imaginary part of the
161  * plus-polarization, the real part of the cross-polarization, and the
162  * imaginary part of the cross-polarization.
163  *
164  * The command:
165  *
166  * lalsim-inspiral --m1=10 --m2=10 --approx=TaylorF2 --condition
167  *
168  * produces the same waveform as in the previous example, but in the
169  * time domain and conditioned so that it is suitable for injection
170  * into detector data.
171  */
172 
173 #include <complex.h>
174 #include <math.h>
175 #include <stdio.h>
176 #include <stdlib.h>
177 #include <time.h>
178 
179 #include <lal/Date.h>
180 #include <lal/LALgetopt.h>
181 #include <lal/Units.h>
182 #include <lal/Sequence.h>
183 #include <lal/TimeSeries.h>
184 #include <lal/FrequencySeries.h>
185 #include <lal/TimeFreqFFT.h>
186 #include <lal/BandPassTimeSeries.h>
187 #include <lal/VectorOps.h>
188 #include <lal/LALConstants.h>
189 #include <lal/LALDatatypes.h>
190 #include <lal/LALError.h>
191 #include <lal/LALString.h>
192 #include <lal/LALDict.h>
193 #include <lal/LALSimInspiral.h>
194 #include <lal/LALSimIMR.h>
195 
196 /* default values of parameters */
197 #define DEFAULT_APPROX "TaylorT1"
198 #define DEFAULT_DOMAIN -1
199 #define DEFAULT_PHASEO -1
200 #define DEFAULT_AMPO -1
201 #define DEFAULT_PHIREF 0.0
202 #define DEFAULT_MEANPERANO 0.0
203 #define DEFAULT_LONGASCNODE 0.0
204 #define DEFAULT_ECCENTRICITY 0.0
205 #define DEFAULT_FREF 0.0
206 #define DEFAULT_SRATE 16384.0
207 #define DEFAULT_M1 1.4
208 #define DEFAULT_M2 1.4
209 #define DEFAULT_F_MIN 40.0
210 #define DEFAULT_DISTANCE 1.0
211 #define DEFAULT_INCLINATION 0.0
212 #define DEFAULT_S1X 0.0
213 #define DEFAULT_S1Y 0.0
214 #define DEFAULT_S1Z 0.0
215 #define DEFAULT_S2X 0.0
216 #define DEFAULT_S2Y 0.0
217 #define DEFAULT_S2Z 0.0
218 #define DEFAULT_LAMBDA1 0.0
219 #define DEFAULT_LAMBDA2 0.0
220 #define DEFAULT_DQUADMON1 0.0
221 #define DEFAULT_DQUADMON2 0.0
222 
223 /* parameters given in command line arguments */
224 struct params {
225  int verbose;
226  int freq_dom;
230  int domain;
231  double phiRef;
232  double meanPerAno;
233  double longAscNodes;
234  double eccentricity;
235  double fRef;
236  double srate;
237  double m1;
238  double m2;
239  double f_min;
240  double distance;
241  double inclination;
242  double s1x;
243  double s1y;
244  double s1z;
245  double s2x;
246  double s2y;
247  double s2z;
248  LALDict *params;
249 };
250 
251 int usage(const char *program);
252 struct params parseargs(int argc, char **argv);
260 double imr_time_bound(double f_min, double m1, double m2, double s1z, double s2z);
261 
262 int main(int argc, char *argv[])
263 {
264  struct params p;
265  int istd, isfd;
266 
268 
269  p = parseargs(argc, argv);
270  print_params(p);
271 
272  /* sanity check on domain; set to natural value if unspecified */
275  if (!istd && !isfd) {
276  fprintf(stderr, "error: approximant not supported\n");
277  exit(1);
278  }
279  switch (p.domain) {
280  case LAL_SIM_DOMAIN_TIME:
281  if (!istd) {
282  fprintf(stderr, "error: approximant not supported in time domain\n");
283  exit(1);
284  }
285  break;
287  if (!isfd) {
288  fprintf(stderr, "error: approximant not supported in frequency domain\n");
289  exit(1);
290  }
291  break;
292  default:
293  switch (p.freq_dom) {
294  case 0:
296  break;
297  case 1:
299  break;
300  }
301  break;
302  }
303 
304  /* generate and output the waveform in appropriate domain */
305  if (p.freq_dom) {
306  COMPLEX16FrequencySeries *htilde_plus = NULL;
307  COMPLEX16FrequencySeries *htilde_cross = NULL;
308  create_fd_waveform(&htilde_plus, &htilde_cross, p);
309  output_fd_waveform(htilde_plus, htilde_cross, p);
312  } else {
313  REAL8TimeSeries *h_plus = NULL;
314  REAL8TimeSeries *h_cross = NULL;
315  create_td_waveform(&h_plus, &h_cross, p);
316  output_td_waveform(h_plus, h_cross, p);
319  }
320 
321  /* cleanup */
322  XLALDestroyDict(p.params);
324  return 0;
325 }
326 
327 /* writes a time-domain waveform to stdout as tab-separated values */
328 int output_td_waveform(REAL8TimeSeries * h_plus, REAL8TimeSeries * h_cross, struct params p)
329 {
330  double t0;
331  size_t j;
332  t0 = XLALGPSGetREAL8(&h_plus->epoch);
333  if (p.amp_phase) {
336  double phi0;
337 
338  /* compute the amplitude and phase of h+ - i hx */
339  for (j = 0; j < h_plus->data->length; ++j) {
340  double complex z = h_plus->data->data[j] - I * h_cross->data->data[j];
341  amp->data[j] = cabs(z);
342  phi->data[j] = carg(z);
343  }
344 
345  /* unwrap the phase */
346  XLALREAL8VectorUnwrapAngle(phi, phi);
347 
348  /* make phase in range -pi to +pi at end of waveform */
349  /* extrapolate the end of the waveform using last and second last points */
350  phi0 = 2 * phi->data[phi->length - 1] - phi->data[phi->length - 2];
351  // phi0 = phi->data[phi->length - 1];
352  phi0 -= fmod(phi0 + copysign(LAL_PI, phi0), 2.0 * LAL_PI) - copysign(LAL_PI, phi0);
353  for (j = 0; j < phi->length; ++j)
354  phi->data[j] -= phi0;
355 
356  fprintf(stdout, "# time (s)\th_abs (strain)\t h_arg (rad)\n");
357  for (j = 0; j < h_plus->data->length; ++j)
358  fprintf(stdout, "%.9f\t%.18e\t%.18e\n", t0 + j * h_plus->deltaT, amp->data[j], phi->data[j]);
359 
362  } else {
363  fprintf(stdout, "# time (s)\th_+ (strain)\th_x (strain)\n");
364  for (j = 0; j < h_plus->data->length; ++j)
365  fprintf(stdout, "%.9f\t%.18e\t%.18e\n", t0 + j * h_plus->deltaT, h_plus->data->data[j], h_cross->data->data[j]);
366  }
367  return 0;
368 }
369 
370 /* writes a frequency-domain waveform to stdout as tab-separated values */
372 {
373  size_t k;
374  if (p.amp_phase) {
375  REAL8Sequence *abs_plus = XLALCreateREAL8Sequence(htilde_plus->data->length);
376  REAL8Sequence *arg_plus = XLALCreateREAL8Sequence(htilde_plus->data->length);
377  REAL8Sequence *abs_cross = XLALCreateREAL8Sequence(htilde_cross->data->length);
378  REAL8Sequence *arg_cross = XLALCreateREAL8Sequence(htilde_cross->data->length);
379  double arg0;
380  size_t kref;
381 
382  /* convert h+ and hx to polar */
383  XLALCOMPLEX16VectorAbs(abs_plus, htilde_plus->data);
384  XLALCOMPLEX16VectorArg(arg_plus, htilde_plus->data);
385  XLALCOMPLEX16VectorAbs(abs_cross, htilde_cross->data);
386  XLALCOMPLEX16VectorArg(arg_cross, htilde_cross->data);
387 
388  /* unwrap the phases */
389  XLALREAL8VectorUnwrapAngle(arg_plus, arg_plus);
390  XLALREAL8VectorUnwrapAngle(arg_cross, arg_cross);
391 
392  /* make sure that unwound phases are in -pi to pi at fRef */
393  kref = round((p.fRef > 0 ? p.fRef : p.f_min) / htilde_plus->deltaF);
394  arg0 = arg_plus->data[kref];
395  arg0 -= fmod(arg0 + copysign(LAL_PI, arg0), 2.0 * LAL_PI) - copysign(LAL_PI, arg0);
396  for (k = 0; k < arg_plus->length; ++k)
397  arg_plus->data[k] -= arg0;
398 
399  arg0 = arg_cross->data[kref];
400  arg0 -= fmod(arg0 + copysign(LAL_PI, arg0), 2.0 * LAL_PI) - copysign(LAL_PI, arg0);
401  for (k = 0; k < arg_cross->length; ++k)
402  arg_cross->data[k] -= arg0;
403 
404  fprintf(stdout, "# freq (s^-1)\tabs_htilde_+ (strain s)\targ_htilde_+ (rad)\tabs_htilde_x (strain s)\targ_htilde_x (rad)\n");
405  for (k = 0; k < htilde_plus->data->length; ++k)
406  fprintf(stdout, "%f\t%.18e\t%.18e\t%.18e\t%.18e\n", k * htilde_plus->deltaF, abs_plus->data[k], arg_plus->data[k],
407  abs_cross->data[k], arg_cross->data[k]);
408 
409  XLALDestroyREAL8Sequence(arg_cross);
410  XLALDestroyREAL8Sequence(abs_cross);
411  XLALDestroyREAL8Sequence(arg_plus);
412  XLALDestroyREAL8Sequence(abs_plus);
413  } else {
414  fprintf(stdout, "# freq (s^-1)\treal_htilde_+ (strain s)\timag_htilde_+ (strain s)\treal_htilde_x (strain s)\timag_htilde_x (strain s)\n");
415  for (k = 0; k < htilde_plus->data->length; ++k)
416  fprintf(stdout, "%f\t%.18e\t%.18e\t%.18e\t%.18e\n", k * htilde_plus->deltaF, creal(htilde_plus->data->data[k]),
417  cimag(htilde_plus->data->data[k]), creal(htilde_cross->data->data[k]), cimag(htilde_cross->data->data[k]));
418  }
419  return 0;
420 }
421 
422 /* creates a waveform in the time domain; the waveform might be generated in
423  * the frequency-domain and transformed */
424 int create_td_waveform(REAL8TimeSeries ** h_plus, REAL8TimeSeries ** h_cross, struct params p)
425 {
426  clock_t timer_start = 0;
427 
428  if (p.condition) {
429  if (p.verbose) {
430  fprintf(stderr, "generating waveform in time domain using XLALSimInspiralTD...\n");
431  timer_start = clock();
432  }
433  XLALSimInspiralTD(h_plus, h_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, 1.0 / p.srate, p.f_min, p.fRef, p.params, p.approx);
434  if (p.verbose)
435  fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
436  } else if (p.domain == LAL_SIM_DOMAIN_TIME) {
437  /* generate time domain waveform */
438  if (p.verbose) {
439  fprintf(stderr, "generating waveform in time domain using XLALSimInspiralChooseTDWaveform...\n");
440  timer_start = clock();
441  }
442  XLALSimInspiralChooseTDWaveform(h_plus, h_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, 1.0 / p.srate, p.f_min, p.fRef, p.params, p.approx);
443  if (p.verbose)
444  fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
445  } else {
446  COMPLEX16FrequencySeries *htilde_plus = NULL;
447  COMPLEX16FrequencySeries *htilde_cross = NULL;
448  REAL8FFTPlan *plan;
449  double chirplen, deltaF;
450  int chirplen_exp;
451 
452  /* determine required frequency resolution */
453  /* length of the chirp in samples */
454  chirplen = imr_time_bound(p.f_min, p.m1, p.m2, p.s1z, p.s2z) * p.srate;
455  /* make chirplen next power of two */
456  frexp(chirplen, &chirplen_exp);
457  chirplen = ldexp(1.0, chirplen_exp);
458  deltaF = p.srate / chirplen;
459  if (p.verbose)
460  fprintf(stderr, "using frequency resolution deltaF = %g Hz\n", deltaF);
461 
462  /* generate waveform in frequency domain */
463  if (p.verbose) {
464  fprintf(stderr, "generating waveform in frequency domain using XLALSimInspiralChooseFDWaveform...\n");
465  timer_start = clock();
466  }
467  XLALSimInspiralChooseFDWaveform(&htilde_plus, &htilde_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, deltaF, p.f_min, 0.5 * p.srate, p.fRef, p.params, p.approx);
468  if (p.verbose)
469  fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
470 
471  /* put the waveform in the time domain */
472  if (p.verbose) {
473  fprintf(stderr, "transforming waveform to time domain...\n");
474  timer_start = clock();
475  }
476  *h_plus = XLALCreateREAL8TimeSeries("h_plus", &htilde_plus->epoch, 0.0, 1.0 / p.srate, &lalStrainUnit, (size_t) chirplen);
477  *h_cross = XLALCreateREAL8TimeSeries("h_cross", &htilde_cross->epoch, 0.0, 1.0 / p.srate, &lalStrainUnit, (size_t) chirplen);
478  plan = XLALCreateReverseREAL8FFTPlan((size_t) chirplen, 0);
479  XLALREAL8FreqTimeFFT(*h_cross, htilde_cross, plan);
480  XLALREAL8FreqTimeFFT(*h_plus, htilde_plus, plan);
481  if (p.verbose)
482  fprintf(stderr, "transformation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
483 
484  /* clean up */
488  }
489 
490  return 0;
491 }
492 
493 /* creates a waveform in the frequency domain; the waveform might be generated
494  * in the time-domain and transformed */
495 int create_fd_waveform(COMPLEX16FrequencySeries ** htilde_plus, COMPLEX16FrequencySeries ** htilde_cross, struct params p)
496 {
497  clock_t timer_start = 0;
498  double chirplen, deltaF;
499  int chirplen_exp;
500 
501  /* length of the chirp in samples */
502  chirplen = imr_time_bound(p.f_min, p.m1, p.m2, p.s1z, p.s2z) * p.srate;
503  /* make chirplen next power of two */
504  frexp(chirplen, &chirplen_exp);
505  chirplen = ldexp(1.0, chirplen_exp);
506  deltaF = p.srate / chirplen;
507  if (p.verbose)
508  fprintf(stderr, "using frequency resolution deltaF = %g Hz\n", deltaF);
509 
510  if (p.condition) {
511  if (p.verbose) {
512  fprintf(stderr, "generating waveform in frequency domain using XLALSimInspiralFD...\n");
513  timer_start = clock();
514  }
515  XLALSimInspiralFD(htilde_plus, htilde_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, deltaF, p.f_min, 0.5 * p.srate, p.fRef, p.params, p.approx);
516  if (p.verbose)
517  fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
518  } else if (p.domain == LAL_SIM_DOMAIN_FREQUENCY) {
519  if (p.verbose) {
520  fprintf(stderr, "generating waveform in frequency domain using XLALSimInspiralChooseFDWaveform...\n");
521  timer_start = clock();
522  }
523  XLALSimInspiralChooseFDWaveform(htilde_plus, htilde_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, deltaF, p.f_min, 0.5 * p.srate, p.fRef, p.params, p.approx);
524  if (p.verbose)
525  fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
526  } else {
527  REAL8TimeSeries *h_plus = NULL;
528  REAL8TimeSeries *h_cross = NULL;
529  REAL8FFTPlan *plan;
530 
531  /* generate time domain waveform */
532  if (p.verbose) {
533  fprintf(stderr, "generating waveform in time domain using XLALSimInspiralChooseTDWaveform...\n");
534  timer_start = clock();
535  }
536  XLALSimInspiralChooseTDWaveform(&h_plus, &h_cross, p.m1, p.m2, p.s1x, p.s1y, p.s1z, p.s2x, p.s2y, p.s2z, p.distance, p.inclination, p.phiRef, p.longAscNodes, p.eccentricity, p.meanPerAno, 1.0 / p.srate, p.f_min, p.fRef, p.params, p.approx);
537  if (p.verbose)
538  fprintf(stderr, "generation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
539 
540  /* resize the waveforms to the required length */
541  XLALResizeREAL8TimeSeries(h_plus, h_plus->data->length - (size_t) chirplen, (size_t) chirplen);
542  XLALResizeREAL8TimeSeries(h_cross, h_cross->data->length - (size_t) chirplen, (size_t) chirplen);
543 
544  /* put the waveform in the frequency domain */
545  /* (the units will correct themselves) */
546  if (p.verbose) {
547  fprintf(stderr, "transforming waveform to frequency domain...\n");
548  timer_start = clock();
549  }
550  *htilde_plus = XLALCreateCOMPLEX16FrequencySeries("htilde_plus", &h_plus->epoch, 0.0, deltaF, &lalDimensionlessUnit, (size_t) chirplen / 2 + 1);
551  *htilde_cross = XLALCreateCOMPLEX16FrequencySeries("htilde_cross", &h_cross->epoch, 0.0, deltaF, &lalDimensionlessUnit, (size_t) chirplen / 2 + 1);
552  plan = XLALCreateForwardREAL8FFTPlan((size_t) chirplen, 0);
553  XLALREAL8TimeFreqFFT(*htilde_cross, h_cross, plan);
554  XLALREAL8TimeFreqFFT(*htilde_plus, h_plus, plan);
555  if (p.verbose)
556  fprintf(stderr, "transformation took %g seconds\n", (double)(clock() - timer_start) / CLOCKS_PER_SEC);
557 
558  /* clean up */
562  }
563  return 0;
564 }
565 
566 /* routine to crudely overestimate the duration of the inspiral, merger, and ringdown */
567 double imr_time_bound(double f_min, double m1, double m2, double s1z, double s2z)
568 {
569  double tchirp, tmerge;
570  double s;
571 
572  /* lower bound on the chirp time starting at f_min */
574 
575  /* upper bound on the final black hole spin */
577 
578  /* lower bound on the final plunge, merger, and ringdown time */
580 
581  return tchirp + tmerge;
582 }
583 
584 /* returns the string corresponding to a particular frame axis enum value */
586 {
587  switch (axis) {
589  return "View";
591  return "TotalJ";
593  return "OrbitalL";
594  default:
595  fprintf(stderr, "error: unknown frame axis\n");
596  exit(1);
597  }
598  return NULL;
599 }
600 
601 /* returns the string corresponding to a particular mode choice enum value */
603 {
604  switch (modes) {
605  case LAL_SIM_INSPIRAL_MODES_CHOICE_RESTRICTED:
606  return "L2";
608  return "L3";
610  return "L4";
612  return "L23";
614  return "L24";
616  return "L34";
618  return "L234";
620  return "L5";
622  return "L25";
624  return "L35";
626  return "L45";
628  return "L235";
630  return "L245";
632  return "L345";
634  return "ALL";
635  default:
636  fprintf(stderr, "error: unknown modes choice\n");
637  exit(1);
638  }
639  return NULL;
640 }
641 
642 /* prints the chosen waveform parameters to stderr if verbosity is set */
643 int print_params(struct params p)
644 {
645  if (p.verbose) {
652  fprintf(stderr, "approximant: %s\n", XLALSimInspiralGetStringFromApproximant(p.approx));
653  if (phaseO == -1)
654  fprintf(stderr, "phase post-Newtonian order: highest available\n");
655  else
656  fprintf(stderr, "twice phase post-Newtonian order: %d (%g pN)\n", phaseO, 0.5 * phaseO);
657  if (ampO == -1)
658  fprintf(stderr, "amplitude post-Newtonian order: highest available\n");
659  else
660  fprintf(stderr, "twice amplitude post-Newtonian order: %d (%g pN)\n", ampO, 0.5 * ampO);
661  if (spinO == -1)
662  fprintf(stderr, "spin post-Newtonian order: highest available\n");
663  else
664  fprintf(stderr, "twice spin post-Newtonian order: %d (%g pN)\n", spinO, 0.5 * spinO);
665  if (tideO == -1)
666  fprintf(stderr, "tidal post-Newtonian order: highest available\n");
667  else
668  fprintf(stderr, "twice tidal post-Newtonian order: %d (%g pN)\n", tideO, 0.5 * tideO);
669  fprintf(stderr, "reference phase: %g deg, %g rad\n", p.phiRef / LAL_PI_180, p.phiRef);
670  fprintf(stderr, "sample rate: %g Hz\n", p.srate);
671  fprintf(stderr, "primary mass: %g Msun\n", p.m1 / LAL_MSUN_SI);
672  fprintf(stderr, "secondary mass: %g Msun\n", p.m2 / LAL_MSUN_SI);
673  fprintf(stderr, "primary dimensionless spin vector: (%g, %g, %g)\n", p.s1x, p.s1y, p.s1z);
674  fprintf(stderr, "secondary dimensionless spin vector: (%g, %g, %g)\n", p.s2x, p.s2y, p.s2z);
675  fprintf(stderr, "starting frequency: %g Hz\n", p.f_min);
676  fprintf(stderr, "reference frequency: %g Hz\n", p.fRef);
677  fprintf(stderr, "distance: %g Mpc\n", p.distance / (1e6 * LAL_PC_SI));
678  fprintf(stderr, "inclination: %g deg, %g rad\n", p.inclination / LAL_PI_180, p.inclination);
679  fprintf(stderr, "frame axis: %s\n", frame_axis_to_string(axis));
680  fprintf(stderr, "higher mode l values: %s\n", modes_choice_to_string(modes));
681  if (p.params) {
682  LALDictEntry *param;
683  LALDictIter iter;
684  XLALDictIterInit(&iter, p.params);
685  while ((param = XLALDictIterNext(&iter)) != NULL) {
686  fprintf(stderr, "extra parameters: %s=", XLALDictEntryGetKey(param));
687  XLALValuePrint(XLALDictEntryGetValue(param), fileno(stderr));
688  fprintf(stderr, "\n");
689  }
690  }
691  }
692  return 0;
693 }
694 
695 /* prints the usage message */
696 int usage(const char *program)
697 {
698  int a, c;
699  fprintf(stderr, "usage: %s [options]\n", program);
700  fprintf(stderr, "options [default values in brackets]:\n");
701  fprintf(stderr, "\t-h, --help \tprint this message and exit\n");
702  fprintf(stderr, "\t-v, --verbose \tverbose output\n");
703  fprintf(stderr, "\t-C, --radians \tuse radians rather than decimal degrees\n");
704  fprintf(stderr, "\t-F, --frequency-domain \toutput data in frequency domain\n");
705  fprintf(stderr, "\t-c, --condition-waveform \tapply waveform conditioning\n");
706  fprintf(stderr, "\t-P, --amp-phase \toutput data as amplitude and phase\n");
707  fprintf(stderr, "\t-a APPROX, --approximant=APPROX \n\t\tapproximant [%s]\n", DEFAULT_APPROX);
708  fprintf(stderr, "\t-w WAVEFORM, --waveform=WAVEFORM \n\t\twaveform string giving both approximant and order\n");
709  fprintf(stderr, "\t-D domain, --domain=DOMAIN \n\t\tdomain for waveform generation when both are available\n\t\t{\"time\", \"freq\"} [use natural domain for output]\n");
710  fprintf(stderr, "\t-O PHASEO, --phase-order=PHASEO \n\t\ttwice pN order of phase (-1 == highest) [%d]\n", DEFAULT_PHASEO);
711  fprintf(stderr, "\t-o AMPO, --amp-order=AMPO \n\t\ttwice pN order of amplitude (-1 == highest) [%d]\n", DEFAULT_AMPO);
712  fprintf(stderr, "\t-u PHIREF, --phiRef=PHIREF \n\t\treference phase in degrees [%g]\n", DEFAULT_PHIREF);
713  fprintf(stderr, "\t-U PERIANOM, --periastron-anomaly=PERIANOM\n\t\tmean periastron anomaly in degrees [%g]\n", DEFAULT_MEANPERANO);
714  fprintf(stderr, "\t-W LONGASC, --longitude-ascending-node=LONGASC\n\t\tlongitude of ascending node in degrees [%g]\n", DEFAULT_LONGASCNODE);
715  fprintf(stderr, "\t-e ECC, --eccentricity=ECC \n\t\torbital eccentricity [%g]\n", DEFAULT_ECCENTRICITY);
716  fprintf(stderr, "\t-R SRATE, --sample-rate=SRATE \n\t\tsample rate in Hertz [%g]\n", DEFAULT_SRATE);
717  fprintf(stderr, "\t-M M1, --m1=M1 \n\t\tmass of primary in solar masses [%g]\n", DEFAULT_M1);
718  fprintf(stderr, "\t-m M2, --m2=M2 \n\t\tmass of secondary in solar masses [%g]\n", DEFAULT_M2);
719  fprintf(stderr, "\t-d D, --distance=D \n\t\tdistance in Mpc [%g]\n", DEFAULT_DISTANCE);
720  fprintf(stderr, "\t-i IOTA, --inclination=IOTA \n\t\tinclination in degrees [%g]\n", DEFAULT_INCLINATION);
721  fprintf(stderr, "\t-X S1X, --spin1x=S1X \n\t\tx-component of dimensionless spin of primary [%g]\n", DEFAULT_S1X);
722  fprintf(stderr, "\t-Y S1Y, --spin1y=S1Y \n\t\ty-component of dimensionless spin of primary [%g]\n", DEFAULT_S1Y);
723  fprintf(stderr, "\t-Z S1Z, --spin1z=S1Z \n\t\tz-component of dimensionless spin of primary [%g]\n", DEFAULT_S1Z);
724  fprintf(stderr, "\t-x S2X, --spin2x=S2X \n\t\tx-component of dimensionless spin of secondary [%g]\n", DEFAULT_S2X);
725  fprintf(stderr, "\t-y S2Y, --spin2y=S2Y \n\t\ty-component of dimensionless spin of secondary [%g]\n", DEFAULT_S2Y);
726  fprintf(stderr, "\t-z S2Z, --spin2z=S2Z \n\t\tz-component of dimensionless spin of secondary [%g]\n", DEFAULT_S2Z);
727  fprintf(stderr, "\t-L LAM1, --tidal-lambda1=LAM1 \n\t\tdimensionless tidal deformability of primary [%g]\n", DEFAULT_LAMBDA1);
728  fprintf(stderr, "\t-l LAM2, --tidal-lambda2=LAM2 \n\t\tdimensionless tidal deformability of secondary [%g]\n", DEFAULT_LAMBDA2);
729  fprintf(stderr, "\t-q DQM1, --delta-quad-mon1=DQM1 \n\t\tdifference in quadrupole-monopole term of primary [%g]\n", DEFAULT_DQUADMON1);
730  fprintf(stderr, "\t-Q DQM2, --delta-quad-mon2=DQM2 \n\t\tdifference in quadrupole-monopole term of secondary [%g]\n", DEFAULT_DQUADMON2);
731  fprintf(stderr, "\t-s SPINO, --spin-order=SPINO \n\t\ttwice pN order of spin effects (-1 == all) [%d]\n", LAL_SIM_INSPIRAL_SPIN_ORDER_DEFAULT);
732  fprintf(stderr, "\t-t TIDEO, --tidal-order=TIDEO \n\t\ttwice pN order of tidal effects (-1 == all) [%d]\n", LAL_SIM_INSPIRAL_TIDAL_ORDER_DEFAULT);
733  fprintf(stderr, "\t-f FMIN, --f-min=FMIN \n\t\tfrequency to start waveform in Hertz [%g]\n", DEFAULT_F_MIN);
734  fprintf(stderr, "\t-r FREF, --fRef=FREF \n\t\treference frequency in Hertz [%g]\n", DEFAULT_FREF);
735  fprintf(stderr, "\t-A AXIS, --axis=AXIS \n\t\taxis for PhenSpin {View, TotalJ, OrbitalL} [%s]\n", frame_axis_to_string(LAL_SIM_INSPIRAL_FRAME_AXIS_DEFAULT));
736  fprintf(stderr, "\t-n MODES, --modes=MODES \n\t\tallowed l modes {L2, L23, ..., ALL} [%s]\n", modes_choice_to_string(LAL_SIM_INSPIRAL_MODES_CHOICE_DEFAULT));
737  fprintf(stderr,
738  "\t-p KEY1=VAL1,KEY2=VAL2,..., --params=KEY1=VAL1,KEY2=VAL2,... \n\t\textra parameters as a key-value pair\n");
739  fprintf(stderr, "recognized time-domain approximants:");
740  for (a = 0, c = 0; a < NumApproximants; ++a) {
743  c += fprintf(stderr, "%s%s", c ? ", " : "\n\t", s);
744  if (c > 50)
745  c = 0;
746  }
747  }
748  fprintf(stderr, "\n");
749  fprintf(stderr, "recognized frequency-domain approximants:");
750  for (a = 0, c = 0; a < NumApproximants; ++a) {
753  c += fprintf(stderr, "%s%s", c ? ", " : "\n\t", s);
754  if (c > 50)
755  c = 0;
756  }
757  }
758  fprintf(stderr, "\n");
759  return 0;
760 }
761 
762 /* sets params to default values and parses the command line arguments */
763 struct params parseargs(int argc, char **argv)
764 {
765  int degrees = 1;
766  int phaseO;
767  char *inclination_string = NULL;
768  char *phiRef_string = NULL;
769  char *meanPerAno_string = NULL;
770  char *longAscNodes_string = NULL;
771  char *kv;
772  struct params p = {
773  .verbose = 0,
775  .condition = 0,
776  .freq_dom = 0,
777  .amp_phase = 0,
778  .domain = DEFAULT_DOMAIN,
779  .phiRef = DEFAULT_PHIREF * LAL_PI_180,
780  .meanPerAno = DEFAULT_MEANPERANO * LAL_PI_180,
781  .longAscNodes = DEFAULT_LONGASCNODE * LAL_PI_180,
782  .eccentricity = DEFAULT_ECCENTRICITY,
783  .fRef = DEFAULT_FREF,
784  .srate = DEFAULT_SRATE,
785  .m1 = DEFAULT_M1 * LAL_MSUN_SI,
786  .m2 = DEFAULT_M2 * LAL_MSUN_SI,
787  .f_min = DEFAULT_F_MIN,
788  .distance = DEFAULT_DISTANCE * 1e6 * LAL_PC_SI,
789  .inclination = DEFAULT_INCLINATION * LAL_PI_180,
790  .s1x = DEFAULT_S1X,
791  .s1y = DEFAULT_S1Y,
792  .s1z = DEFAULT_S1Z,
793  .s2x = DEFAULT_S2X,
794  .s2y = DEFAULT_S2Y,
795  .s2z = DEFAULT_S2Z,
796  .params = NULL
797  };
798  struct LALoption long_options[] = {
799  {"help", no_argument, 0, 'h'},
800  {"verbose", no_argument, 0, 'v'},
801  {"radians", no_argument, 0, 'C'},
802  {"frequency-domain", no_argument, 0, 'F'},
803  {"condition-waveform", no_argument, 0, 'c'},
804  {"amp-phase", no_argument, 0, 'P'},
805  {"approximant", required_argument, 0, 'a'},
806  {"waveform", required_argument, 0, 'w'},
807  {"domain", required_argument, 0, 'D'},
808  {"phase-order", required_argument, 0, 'O'},
809  {"amp-order", required_argument, 0, 'o'},
810  {"phiRef", required_argument, 0, 'u'},
811  {"periastron-anomaly", required_argument, 0, 'U'},
812  {"longitude-ascending-node", required_argument, 0, 'W'},
813  {"eccentricity", required_argument, 0, 'e'},
814  {"fRef", required_argument, 0, 'r'},
815  {"sample-rate", required_argument, 0, 'R'},
816  {"m1", required_argument, 0, 'M'},
817  {"m2", required_argument, 0, 'm'},
818  {"spin1x", required_argument, 0, 'X'},
819  {"spin1y", required_argument, 0, 'Y'},
820  {"spin1z", required_argument, 0, 'Z'},
821  {"spin2x", required_argument, 0, 'x'},
822  {"spin2y", required_argument, 0, 'y'},
823  {"spin2z", required_argument, 0, 'z'},
824  {"tidal-lambda1", required_argument, 0, 'L'},
825  {"tidal-lambda2", required_argument, 0, 'l'},
826  {"delta-quad-mon1", required_argument, 0, 'q'},
827  {"delta-quad-mon2", required_argument, 0, 'Q'},
828  {"spin-order", required_argument, 0, 's'},
829  {"tidal-order", required_argument, 0, 't'},
830  {"f-min", required_argument, 0, 'f'},
831  {"f-max", required_argument, 0, 'F'},
832  {"distance", required_argument, 0, 'd'},
833  {"inclination", required_argument, 0, 'i'},
834  {"axis", required_argument, 0, 'A'},
835  {"modes", required_argument, 0, 'n'},
836  {"params", required_argument, 0, 'p'},
837  {0, 0, 0, 0}
838  };
839  char args[] = "hvCFcPa:w:D:O:o:u:U:W:e:r:R:M:m:X:x:Y:y:Z:z:L:l:q:Q:s:t:f:d:i:A:n:p:";
840 
841  while (1) {
842  int option_index = 0;
843  int c;
844 
845  c = LALgetopt_long_only(argc, argv, args, long_options, &option_index);
846  if (c == -1) /* end of options */
847  break;
848 
849  switch (c) {
850  case 0: /* if option set a flag, nothing else to do */
851  if (long_options[option_index].flag)
852  break;
853  else {
854  fprintf(stderr, "error parsing option %s with argument %s\n", long_options[option_index].name, LALoptarg);
855  exit(1);
856  }
857  case 'h': /* help */
858  usage(argv[0]);
859  exit(0);
860  case 'v': /* verbose */
861  p.verbose = 1;
862  break;
863  case 'C': /* radians */
864  degrees = 0;
865  break;
866  case 'F': /* frequency-domain */
867  p.freq_dom = 1;
868  break;
869  case 'c': /* condition-waveform */
870  p.condition = 1;
871  break;
872  case 'P': /* amp-phase */
873  p.amp_phase = 1;
874  break;
875  case 'a': /* approximant */
876  p.approx = XLALSimInspiralGetApproximantFromString(LALoptarg);
877  if ((int)p.approx == XLAL_FAILURE) {
878  fprintf(stderr, "error: invalid value %s for %s\n", LALoptarg, long_options[option_index].name);
879  exit(1);
880  }
881  break;
882  case 'w': /* waveform */
883  p.approx = XLALSimInspiralGetApproximantFromString(LALoptarg);
884  if ((int)p.approx == XLAL_FAILURE) {
885  fprintf(stderr, "error: could not parse approximant from %s for %s\n", LALoptarg, long_options[option_index].name);
886  exit(1);
887  }
888  phaseO = XLALSimInspiralGetPNOrderFromString(LALoptarg);
889  if ((int)phaseO == XLAL_FAILURE) {
890  fprintf(stderr, "error: could not parse order from %s for %s\n", LALoptarg, long_options[option_index].name);
891  exit(1);
892  }
893  if (p.params == NULL)
894  p.params = XLALCreateDict();
896  break;
897  case 'D': /* domain */
898  switch (*LALoptarg) {
899  case 'T':
900  case 't':
901  p.domain = LAL_SIM_DOMAIN_TIME;
902  break;
903  case 'F':
904  case 'f':
905  p.domain = LAL_SIM_DOMAIN_FREQUENCY;
906  break;
907  default:
908  fprintf(stderr, "error: invalid value %s for %s\n", LALoptarg, long_options[option_index].name);
909  exit(1);
910  }
911  break;
912  case 'O': /* phase-order */
913  if (p.params == NULL)
914  p.params = XLALCreateDict();
915  XLALSimInspiralWaveformParamsInsertPNPhaseOrder(p.params, atoi(LALoptarg));
916  break;
917  case 'o': /* amp-order */
918  if (p.params == NULL)
919  p.params = XLALCreateDict();
921  break;
922  case 'u': /* phiRef */
923  phiRef_string = LALoptarg;
924  break;
925  case 'U': /* mean-periastron-anomaly */
926  meanPerAno_string = LALoptarg;
927  break;
928  case 'W': /* longitude-ascending-node */
929  longAscNodes_string = LALoptarg;
930  break;
931  case 'e': /* eccentricity */
932  p.eccentricity = atof(LALoptarg);
933  break;
934  case 'r': /* fRef */
935  p.fRef = atof(LALoptarg);
936  break;
937  case 'R': /* sample-rate */
938  p.srate = atof(LALoptarg);
939  break;
940  case 'M': /* m1 */
941  p.m1 = atof(LALoptarg) * LAL_MSUN_SI;
942  break;
943  case 'm': /* m2 */
944  p.m2 = atof(LALoptarg) * LAL_MSUN_SI;
945  break;
946  case 'X': /* spin1x */
947  p.s1x = atof(LALoptarg);
948  break;
949  case 'Y': /* spin1y */
950  p.s1y = atof(LALoptarg);
951  break;
952  case 'Z': /* spin1z */
953  p.s1z = atof(LALoptarg);
954  break;
955  case 'x': /* spin2x */
956  p.s2x = atof(LALoptarg);
957  break;
958  case 'y': /* spin2y */
959  p.s2y = atof(LALoptarg);
960  break;
961  case 'z': /* spin2z */
962  p.s2z = atof(LALoptarg);
963  break;
964  case 'L': /* tidal-lambda1 */
965  if (p.params == NULL)
966  p.params = XLALCreateDict();
967  XLALSimInspiralWaveformParamsInsertTidalLambda1(p.params, atoi(LALoptarg));
968  break;
969  case 'l': /* tidal-lambda2 */
970  if (p.params == NULL)
971  p.params = XLALCreateDict();
972  XLALSimInspiralWaveformParamsInsertTidalLambda2(p.params, atoi(LALoptarg));
973  break;
974  case 'q': /* diff-quad-mon1 */
975  if (p.params == NULL)
976  p.params = XLALCreateDict();
977  XLALSimInspiralWaveformParamsInsertdQuadMon1(p.params, atoi(LALoptarg));
978  break;
979  case 'Q': /* diff-quad-mon2 */
980  if (p.params == NULL)
981  p.params = XLALCreateDict();
982  XLALSimInspiralWaveformParamsInsertdQuadMon2(p.params, atoi(LALoptarg));
983  break;
984  case 's': /* spin-order */
985  if (p.params == NULL)
986  p.params = XLALCreateDict();
987  XLALSimInspiralWaveformParamsInsertPNSpinOrder(p.params, atoi(LALoptarg));
988  break;
989  case 't': /* tidal-order */
990  if (p.params == NULL)
991  p.params = XLALCreateDict();
992  XLALSimInspiralWaveformParamsInsertPNTidalOrder(p.params, atoi(LALoptarg));
993  break;
994  case 'f': /* f-min */
995  p.f_min = atof(LALoptarg);
996  break;
997  case 'd': /* distance */
998  p.distance = atof(LALoptarg) * 1e6 * LAL_PC_SI;
999  break;
1000  case 'i': /* inclination */
1001  inclination_string = LALoptarg;
1002  break;
1003  case 'A': /* axis */
1004  if (p.params == NULL)
1005  p.params = XLALCreateDict();
1007  break;
1008  case 'n': /* modes */
1009  if (p.params == NULL)
1010  p.params = XLALCreateDict();
1012  break;
1013  case 'p': /* params */
1014  if (p.params == NULL)
1015  p.params = XLALCreateDict();
1016  while ((kv = XLALStringToken(&LALoptarg, ",", 0))) {
1017  char *key = XLALStringToken(&kv, "=", 0);
1018  if (kv == NULL || key == NULL || *key == '\0') {
1019  fprintf(stderr, "error: invalid key-value pair for %s\n", long_options[option_index].name);
1020  exit(1);
1021  }
1022  XLALDictInsertREAL8Value(p.params, key, atof(kv));
1023  }
1024  break;
1025  case '?':
1026  default:
1027  fprintf(stderr, "unknown error while parsing options\n");
1028  exit(1);
1029  }
1030  }
1031  if (LALoptind < argc) {
1032  fprintf(stderr, "extraneous command line arguments:\n");
1033  while (LALoptind < argc)
1034  fprintf(stderr, "%s\n", argv[LALoptind++]);
1035  exit(1);
1036  }
1037 
1038  /* set angles, converting to degrees to radians if needed */
1039  if (phiRef_string) {
1040  p.phiRef = atof(phiRef_string);
1041  if (degrees)
1042  p.phiRef *= LAL_PI_180;
1043  }
1044  if (inclination_string) {
1045  p.inclination = atof(inclination_string);
1046  if (degrees)
1047  p.inclination *= LAL_PI_180;
1048  }
1049  if (meanPerAno_string) {
1050  p.meanPerAno = atof(meanPerAno_string);
1051  if (degrees)
1052  p.meanPerAno *= LAL_PI_180;
1053  }
1054  if (longAscNodes_string) {
1055  p.longAscNodes = atof(longAscNodes_string);
1056  if (degrees)
1057  p.longAscNodes *= LAL_PI_180;
1058  }
1059 
1060  return p;
1061 }
const char * XLALDictEntryGetKey(const LALDictEntry *entry)
LALDictEntry * XLALDictIterNext(LALDictIter *iter)
void XLALDestroyDict(LALDict *dict)
void XLALDictIterInit(LALDictIter *iter, LALDict *dict)
const LALValue * XLALDictEntryGetValue(const LALDictEntry *entry)
LALDict * XLALCreateDict(void)
int XLALDictInsertREAL8Value(LALDict *dict, const char *key, REAL8 value)
void LALCheckMemoryLeaks(void)
REAL8 XLALSimInspiralChirpTimeBound(REAL8 fstart, REAL8 m1, REAL8 m2, REAL8 s1, REAL8 s2)
Routine to compute an overestimate of the inspiral time from a given frequency.
const char * XLALSimInspiralGetStringFromApproximant(Approximant approximant)
Returns a string associated with an Approximant enum value.
REAL8 XLALSimInspiralMergeTimeBound(REAL8 m1, REAL8 m2)
Routine to compute an overestimate of the merger time.
int XLALSimInspiralGetPNOrderFromString(const char *waveform)
Parses a waveform string to determine PN order.
int XLALSimInspiralGetHigherModesFromString(const char *string)
Parses a string to determine the LALSimInspiralModesChoice enum value.
int XLALSimInspiralImplementedFDApproximants(Approximant approximant)
Checks whether the given approximant is implemented in lalsimulation's XLALSimInspiralChooseFDWavefor...
REAL8 XLALSimInspiralRingdownTimeBound(REAL8 M, REAL8 s)
Routine to compute an overestimate of the ringdown time.
int XLALSimInspiralGetFrameAxisFromString(const char *waveform)
Parses a waveform string to determine frame axis.
REAL8 XLALSimInspiralFinalBlackHoleSpinBound(REAL8 S1z, REAL8 S2z)
Routine to compute an overestimate of a final black hole dimensionless spin.
int XLALSimInspiralImplementedTDApproximants(Approximant approximant)
Checks whether the given approximant is implemented in lalsimulation's XLALSimInspiralChooseTDWavefor...
int XLALSimInspiralGetApproximantFromString(const char *waveform)
Parses a waveform string to determine approximant.
#define c
int XLALSimInspiralWaveformParamsInsertPNPhaseOrder(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertTidalLambda1(LALDict *params, REAL8 value)
INT4 XLALSimInspiralWaveformParamsLookupFrameAxis(LALDict *params)
int XLALSimInspiralWaveformParamsInsertModesChoice(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertFrameAxis(LALDict *params, INT4 value)
INT4 XLALSimInspiralWaveformParamsLookupModesChoice(LALDict *params)
INT4 XLALSimInspiralWaveformParamsLookupPNPhaseOrder(LALDict *params)
int XLALSimInspiralWaveformParamsInsertPNSpinOrder(LALDict *params, INT4 value)
INT4 XLALSimInspiralWaveformParamsLookupPNAmplitudeOrder(LALDict *params)
int XLALSimInspiralWaveformParamsInsertTidalLambda2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPNAmplitudeOrder(LALDict *params, INT4 value)
INT4 XLALSimInspiralWaveformParamsLookupPNTidalOrder(LALDict *params)
int XLALSimInspiralWaveformParamsInsertdQuadMon2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPNTidalOrder(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertdQuadMon1(LALDict *params, REAL8 value)
INT4 XLALSimInspiralWaveformParamsLookupPNSpinOrder(LALDict *params)
const char * name
#define char
Definition: LALSimUnicorn.c:14
void XLALValuePrint(const LALValue *value, int fd)
int LALgetopt_long_only(int argc, char *const *argv, const char *options, const struct LALoption *long_options, int *opt_index)
char * LALoptarg
#define no_argument
#define required_argument
#define fprintf
int s
Definition: bh_qnmode.c:137
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALDestroyCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series)
#define LAL_MSUN_SI
#define LAL_PI_180
#define LAL_PI
#define LAL_PC_SI
int XLALSimInspiralChooseFDWaveform(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, const REAL8 m1, const REAL8 m2, const REAL8 S1x, const REAL8 S1y, const REAL8 S1z, const REAL8 S2x, const REAL8 S2y, const REAL8 S2z, const REAL8 distance, const REAL8 inclination, const REAL8 phiRef, const REAL8 longAscNodes, const REAL8 eccentricity, const REAL8 UNUSED meanPerAno, const REAL8 deltaF, const REAL8 f_min, const REAL8 f_max, REAL8 f_ref, LALDict *params, const Approximant approximant)
Chooses between different approximants when requesting a waveform to be generated For spinning wavefo...
int XLALSimInspiralFD(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, REAL8 m1, REAL8 m2, REAL8 S1x, REAL8 S1y, REAL8 S1z, REAL8 S2x, REAL8 S2y, REAL8 S2z, REAL8 distance, REAL8 inclination, REAL8 phiRef, REAL8 longAscNodes, REAL8 eccentricity, REAL8 meanPerAno, REAL8 deltaF, REAL8 f_min, REAL8 f_max, REAL8 f_ref, LALDict *LALparams, Approximant approximant)
Generates a frequency domain inspiral waveform using the specified approximant; the resulting wavefor...
int XLALSimInspiralChooseTDWaveform(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const REAL8 m1, const REAL8 m2, const REAL8 S1x, const REAL8 S1y, const REAL8 S1z, const REAL8 S2x, const REAL8 S2y, const REAL8 S2z, const REAL8 distance, const REAL8 inclination, const REAL8 phiRef, const REAL8 longAscNodes, const REAL8 eccentricity, const REAL8 UNUSED meanPerAno, const REAL8 deltaT, const REAL8 f_min, REAL8 f_ref, LALDict *params, const Approximant approximant)
Chooses between different approximants when requesting a waveform to be generated For spinning wavefo...
int XLALSimInspiralTD(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 m1, REAL8 m2, REAL8 S1x, REAL8 S1y, REAL8 S1z, REAL8 S2x, REAL8 S2y, REAL8 S2z, REAL8 distance, REAL8 inclination, REAL8 phiRef, REAL8 longAscNodes, REAL8 eccentricity, REAL8 meanPerAno, REAL8 deltaT, REAL8 f_min, REAL8 f_ref, LALDict *LALparams, Approximant approximant)
Generates an time domain inspiral waveform using the specified approximant; the resulting waveform is...
LALSimInspiralModesChoice
Enumerator for choosing which modes to include in IMR models.
#define LAL_SIM_INSPIRAL_FRAME_AXIS_DEFAULT
#define LAL_SIM_INSPIRAL_TIDAL_ORDER_DEFAULT
LALSimInspiralFrameAxis
Enumerator for choosing the reference frame associated with PSpinInspiralRD waveforms.
Approximant
Enum that specifies the PN approximant to be used in computing the waveform.
#define LAL_SIM_INSPIRAL_SPIN_ORDER_DEFAULT
Default values for all enumerated flags.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_3L
Inlude only l=3 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_DEFAULT
Include only (2,2) or l=2 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_4AND5L
Inlude l=4,5 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_4L
Inlude only l=4 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_ALL
Include all available modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_2AND3L
Inlude l=2,3 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_2AND3AND5L
Inlude l=2,3,5 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_3AND4L
Include l=3,4 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_2AND5L
Inlude l=2,5 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_3AND5L
Inlude l=3,5 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_5L
Inlude only l=5 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_2AND4AND5L
Inlude l=2,4,5 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_2AND3AND4L
Include l=2,3,4 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_3AND4AND5L
Inlude l=3,4,5 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_2AND4L
Include l=2,4 modes.
@ LAL_SIM_DOMAIN_TIME
@ LAL_SIM_DOMAIN_FREQUENCY
@ LAL_SIM_INSPIRAL_FRAME_AXIS_VIEW
Set z-axis along direction of GW propagation (line of sight)
@ LAL_SIM_INSPIRAL_FRAME_AXIS_TOTAL_J
Set z-axis along the initial total angular momentum.
@ LAL_SIM_INSPIRAL_FRAME_AXIS_ORBITAL_L
Set z-axis along the initial orbital angular momentum.
@ NumApproximants
Number of elements in enum, useful for checking bounds.
char * XLALStringToken(char **s, const char *delim, int empty)
static const INT4 a
void XLALDestroyREAL8FFTPlan(REAL8FFTPlan *plan)
REAL8FFTPlan * XLALCreateReverseREAL8FFTPlan(UINT4 size, int measurelvl)
REAL8FFTPlan * XLALCreateForwardREAL8FFTPlan(UINT4 size, int measurelvl)
void XLALDestroyREAL8Sequence(REAL8Sequence *sequence)
REAL8Sequence * XLALCreateREAL8Sequence(size_t length)
int XLALREAL8TimeFreqFFT(COMPLEX16FrequencySeries *freq, const REAL8TimeSeries *tser, const REAL8FFTPlan *plan)
int XLALREAL8FreqTimeFFT(REAL8TimeSeries *tser, const COMPLEX16FrequencySeries *freq, const REAL8FFTPlan *plan)
REAL8TimeSeries * XLALResizeREAL8TimeSeries(REAL8TimeSeries *series, int first, size_t length)
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 lalDimensionlessUnit
int XLALREAL8VectorUnwrapAngle(REAL8Vector *out, const REAL8Vector *in)
int XLALCOMPLEX16VectorArg(REAL8Vector *out, const COMPLEX16Vector *in)
int XLALCOMPLEX16VectorAbs(REAL8Vector *out, const COMPLEX16Vector *in)
void XLALBacktraceErrorHandler(const char *func, const char *file, int line, int errnum)
XLALErrorHandlerType * XLALSetErrorHandler(XLALErrorHandlerType *newHandler)
XLAL_FAILURE
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
char * program
Definition: inject.c:87
#define DEFAULT_PHASEO
Definition: inspiral.c:199
int print_params(struct params params)
#define DEFAULT_LAMBDA1
Definition: inspiral.c:218
int main(int argc, char *argv[])
Definition: inspiral.c:262
int output_fd_waveform(COMPLEX16FrequencySeries *htilde_plus, COMPLEX16FrequencySeries *htilde_cross, struct params params)
#define DEFAULT_S2Z
Definition: inspiral.c:217
int usage(const char *program)
Definition: inspiral.c:696
#define DEFAULT_SRATE
Definition: inspiral.c:206
#define DEFAULT_PHIREF
Definition: inspiral.c:201
#define DEFAULT_LAMBDA2
Definition: inspiral.c:219
#define DEFAULT_S2X
Definition: inspiral.c:215
int create_td_waveform(REAL8TimeSeries **h_plus, REAL8TimeSeries **h_cross, struct params params)
#define DEFAULT_FREF
Definition: inspiral.c:205
#define DEFAULT_MEANPERANO
Definition: inspiral.c:202
#define DEFAULT_DQUADMON1
Definition: inspiral.c:220
#define DEFAULT_M2
Definition: inspiral.c:208
#define DEFAULT_LONGASCNODE
Definition: inspiral.c:203
#define DEFAULT_DQUADMON2
Definition: inspiral.c:221
const char * modes_choice_to_string(LALSimInspiralModesChoice modes)
Definition: inspiral.c:602
#define DEFAULT_F_MIN
Definition: inspiral.c:209
#define DEFAULT_APPROX
Definition: inspiral.c:197
#define DEFAULT_DISTANCE
Definition: inspiral.c:210
int create_fd_waveform(COMPLEX16FrequencySeries **htilde_plus, COMPLEX16FrequencySeries **htilde_cross, struct params params)
#define DEFAULT_S1X
Definition: inspiral.c:212
#define DEFAULT_S2Y
Definition: inspiral.c:216
#define DEFAULT_S1Y
Definition: inspiral.c:213
#define DEFAULT_S1Z
Definition: inspiral.c:214
#define DEFAULT_ECCENTRICITY
Definition: inspiral.c:204
#define DEFAULT_DOMAIN
Definition: inspiral.c:198
#define DEFAULT_INCLINATION
Definition: inspiral.c:211
struct params parseargs(int argc, char **argv)
Definition: inspiral.c:763
#define DEFAULT_AMPO
Definition: inspiral.c:200
#define DEFAULT_M1
Definition: inspiral.c:207
int output_td_waveform(REAL8TimeSeries *h_plus, REAL8TimeSeries *h_cross, struct params params)
const char * frame_axis_to_string(LALSimInspiralFrameAxis axis)
Definition: inspiral.c:585
double imr_time_bound(double f_min, double m1, double m2, double s1z, double s2z)
Definition: inspiral.c:567
list p
COMPLEX16Sequence * data
COMPLEX16 * data
int * flag
REAL8Sequence * data
LIGOTimeGPS epoch
REAL8 * data
Definition: burst.c:245
double srate
Definition: burst.c:256
double meanPerAno
Definition: inspiral.c:232
Approximant approx
Definition: inspiral.c:229
double phiRef
Definition: inspiral.c:231
double inclination
Definition: inspiral.c:241
double m1
Definition: inspiral.c:237
double fRef
Definition: inspiral.c:235
double s2y
Definition: inspiral.c:246
double s1y
Definition: inspiral.c:243
double longAscNodes
Definition: inspiral.c:233
double s2x
Definition: inspiral.c:245
int domain
Definition: inspiral.c:230
double f_min
Definition: inspiral.c:239
double eccentricity
Definition: burst.c:252
double m2
Definition: inspiral.c:238
int amp_phase
Definition: inspiral.c:228
int condition
Definition: inspiral.c:227
int freq_dom
Definition: inspiral.c:226
double s1z
Definition: inspiral.c:244
double distance
Definition: inspiral.c:240
double s2z
Definition: inspiral.c:247
LALDict * params
Definition: inspiral.c:248
double s1x
Definition: inspiral.c:242
double f_min
Definition: unicorn.c:22