Loading [MathJax]/extensions/TeX/AMSsymbols.js
LALSimulation 6.2.0.1-5e288d3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
GenerateSimulation.c
Go to the documentation of this file.
1/*
2* Copyright (C) 2011 Nickolas Fotopoulos, Evan Ochsner, 2016 Riccardo Sturani
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#include <math.h>
21#include <stdlib.h>
22#include <time.h>
23#include <sys/types.h>
24#include <string.h>
25
26#include <lal/LALConstants.h>
27#include <lal/LALDatatypes.h>
28#include <lal/Date.h>
29#include <lal/FrequencySeries.h>
30#include <lal/LALSimInspiral.h>
31#include <lal/LALSimIMR.h>
32#include <lal/XLALError.h>
33#include <lal/LALAdaptiveRungeKuttaIntegrator.h>
34#include <lal/LALSimInspiralWaveformParams.h>
35
36/* internal storage is in SI units! */
37typedef struct GSParams {
38 Approximant approximant; /**< waveform family or "approximant" */
39 LALSimulationDomain domain; /**< flag for time or frequency domain waveform */
40 REAL8 phiRef; /**< phase at fRef */
41 REAL8 fRef; /**< reference frequency */
42 REAL8 deltaT; /**< sampling interval */
43 REAL8 deltaF; /**< frequency resolution */
44 REAL8 m1; /**< mass of companion 1 */
45 REAL8 m2; /**< mass of companion 2 */
46 REAL8 f_min; /**< start frequency */
47 REAL8 f_max; /**< end frequency */
48 REAL8 distance; /**< distance of source */
49 REAL8 inclination; /**< inclination of L relative to line of sight */
50 REAL8 s1x; /**< (x,y,z) components of spin of m1 body */
51 REAL8 s1y; /**< z-axis along line of sight, L in x-z plane */
52 REAL8 s1z; /**< dimensionless spin, Kerr bound: |s1| <= 1 */
53 REAL8 s2x; /**< (x,y,z) component ofs spin of m2 body */
54 REAL8 s2y; /**< z-axis along line of sight, L in x-z plane */
55 REAL8 s2z; /**< dimensionless spin, Kerr bound: |s2| <= 1 */
56 REAL8 longAscNodes; /**< longitude of ascending nodes 0<= omega < 2 pi */
57 REAL8 ecc; /**< eccentricity 0<= ecc < 1 */
58 REAL8 meanPerAno; /**< mean periastron anomaly 0<= psi < 2 Pi */
59 char outname[256]; /**< file to which output should be written */
60 LALDict *params; /**<Container for all accessory parameters */
63 // New interface specific
64 int newinterface; /**< 0 or 1: Old or New interface respectively */
65 int condition; /**< Conditioning waveform for (Inverse)Fourier Transform */
66 char module[256]; /**< Name of the External python module */
67 char object[256]; /**< Name of the python class defined in python-module which includes the methods generate_fd/td_waveform **/
68 int m1_newinterface; /**< Check if mass1 is an input argument */
69 int m2_newinterface; /**< Check if mass2 is an input argument */
70} GSParams;
71
72
73const char * usage =
74"Generate a simulation using the lalsimulation library\n\n"
75"The following options can be given (will assume a default value if omitted):\n"
76"--domain DOM 'TD' for time domain (default) or 'FD' for frequency\n"
77" domain; not all approximants support all domains\n"
78"--amp-phase If given, will output:\n"
79" |h+ - i hx|, Arg(h+ - i hx) (TD) or\n"
80" |h+(f)|, Arg(h+(f)), |hx(f)|, Arg(hx(f)) (FD)\n"
81" If not given, will output h+ and hx (TD and FD)\n"
82"--approximant APPROX Supported TD approximants:\n"
83" TaylorT1 (default)\n"
84" TaylorT2\n"
85" TaylorT3\n"
86" TaylorT4\n"
87" TaylorEt\n"
88" EccentricTD\n"
89" IMRPhenomA\n"
90" IMRPhenomB\n"
91" IMRPhenomC\n"
92" IMRPhenomD\n"
93" IMRPhenomHM\n"
94" IMRPhenomPv2\n"
95" IMRPhenomPv3\n"
96" IMRPhenomPv3HM\n"
97" EOBNRv2\n"
98" EOBNRv2HM\n"
99" SEOBNRv1\n"
100" SEOBNRv2\n"
101" SEOBNRv3\n"
102" SEOBNRv4\n"
103" SEOBNRv4HM\n"
104" SEOBNRv4P\n"
105" SEOBNRv2T\n"
106" SEOBNRv4T\n"
107" TEOBResumS\n"
108" SpinTaylorT4\n"
109" SpinTaylorT5\n"
110" PhenSpinTaylor\n"
111" PhenSpinTaylorRD\n"
112" SpinDominatedWf\n"
113" HGimri\n"
114" NRHybSur3dq8\n"
115" NR_hdf5\n"
116" Supported FD approximants:\n"
117" IMRPhenomA\n"
118" IMRPhenomB\n"
119" IMRPhenomC\n"
120" IMRPhenomD\n"
121" IMRPhenomP\n"
122" IMRPhenomPv2\n"
123" IMRPhenomPv3\n"
124" IMRPhenomPv3HM\n"
125" EOBNRv2_ROM\n"
126" EOBNRv2HM_ROM\n"
127" SEOBNRv1_ROM_EffectiveSpin\n"
128" SEOBNRv1_ROM_DoubleSpin\n"
129" SEOBNRv2_ROM_EffectiveSpin\n"
130" SEOBNRv2_ROM_DoubleSpin\n"
131" SEOBNRv4_ROM\n"
132" SEOBNRv4HM_ROM\n"
133" SEOBNRv5_ROM\n"
134" SEOBNRv5HM_ROM\n"
135" TaylorF2\n"
136" TaylorF2Ecc\n"
137" SpinTaylorF2\n"
138" TaylorR2F4\n"
139" SpinTaylorT4Fourier\n"
140" SpinTaylorT5Fourier\n"
141" TaylorF2RedSpin\n"
142" TaylorF2RedSpinTidal\n"
143" NOTE: Other approximants may be available if the\n"
144" developer forgot to edit this help message\n"
145"--phase-order ORD Twice PN order of phase (default ORD=7 <==> 3.5PN)\n"
146"--amp-order ORD Twice PN order of amplitude (default 0 <==> Newt.)\n"
147"--phiRef PHIREF Phase at the reference frequency (default 0)\n"
148"--fRef FREF Reference frequency in Hz\n"
149" (default: 0)\n"
150"--sample-rate SRATE Sampling rate of TD approximants in Hz (default 4096)\n"
151"--deltaF DF Frequency bin size for FD approximants in Hz (default 1/8)\n"
152"--m1 M1 Mass of the 1st object in solar masses (default 10)\n"
153"--m2 M2 Mass of the 2nd object in solar masses (default 1.4)\n"
154"--inclination IOTA Angle in radians between line of sight (N) and \n"
155" orbital angular momentum (L) at the reference\n"
156" (default 0, face on)\n"
157"--spin1x S1X Vector components for spin of mass1 (default all 0)\n"
158"--spin1y S1Y z-axis=line of sight, L in x-z plane at reference\n"
159"--spin1z S1Z Kerr limit: s1x^2 + s1y^2 + s1z^2 <= 1\n"
160"--spin2x S2X Vector components for spin of mass2 (default all 0)\n"
161"--spin2y S2Y z-axis=line of sight, L in x-z plane at reference\n"
162"--spin2z S2Z Kerr limit: s2x^2 + s2y^2 + s2z^2 <= 1\n"
163"--tidal-lambda1 L1 (tidal deformability of mass 1) / (mass of body 1)^5\n"
164" (~128-2560 for NS, 0 for BH) (default 0)\n"
165"--tidal-lambda2 L2 (tidal deformability of mass 2) / (mass of body 2)^5\n"
166" (~128-2560 for NS, 0 for BH) (default 0)\n"
167"--ecc_order eccO PN order for eccentric correction term\n"
168" (-1 for maximum order) (default -1)\n"
169"--f_ecc f reference frequency for initial eccentricity\n"
170" (10Hz) (default 10)\n"
171"--tidal-lambda-octu1 L31 (octupolar tidal deformability of mass 1) / (mass of body 1)^7\n"
172" (0 for BH) (default 0)\n"
173"--tidal-lambda-octu2 L32 (octupolar tidal deformability of mass 2) / (mass of body 2)^7\n"
174" (0 for BH) (default 0)\n"
175"--tidal-quadfmode1 W21 dimensionless quadrupolar f-mode angular frequency of mass 1, normalized to mass 1\n"
176"--tidal-quadfmode2 W22 dimensionless quadrupolar f-mode angular frequency of mass 2, normalized to mass 2\n"
177"--tidal-octufmode1 W31 dimensionless octupolar f-mode angular frequency of mass 1, normalized to mass 1\n"
178"--tidal-octufmode2 W32 dimensionless octupolar f-mode angular frequency of mass 2, normalized to mass 2\n"
179"--quad-mon1 kappa1 dimensionless quadrupole-monopole parameter of mass 1, value 1 for a black hole\n"
180"--quad-mon2 kappa2 dimensionless quadrupole-monopole parameter of mass 2, value 1 for a black hole\n"
181"--spin-order ORD Twice PN order of spin effects\n"
182" (default ORD=-1 <==> All spin effects)\n"
183"--tidal-order ORD Twice PN order of tidal effects\n"
184" (default ORD=-1 <==> All tidal effects)\n"
185"--f-min FMIN Lower frequency to start waveform in Hz (default 40)\n"
186"--f-max FMAX Frequency at which to stop waveform in Hz\n"
187" (default: generate as much as possible)\n"
188"--distance D Distance in Mpc (default 100)\n"
189"--long-asc-nodes omega Longitude of ascending nodes in radians (default 0)\n"
190"--eccentricity ecc Eccentricity (default 0)\n"
191"--mean-per-ano psi Mean periastron anomaly in radians (default 0)\n"
192"--axis AXIS for PhenSpin: 'View' (default), 'TotalJ', 'OrbitalL'\n"
193"--nr-file for NR_hdf5\n"
194"--nonGRpar NAME VALUE add the nonGRparam with name 'NAME' and value 'VALUE'\n"
195" Supported names:\n"
196" NonGRPhi1\n"
197" NonGRPhi2\n"
198" NonGRPhi3\n"
199" NonGRPhi4\n"
200" NonGRDChi0\n"
201" NonGRDChi1\n"
202" NonGRDChi2\n"
203" NonGRDChi3\n"
204" NonGRDChi4\n"
205" NonGRDChi5\n"
206" NonGRDChi5L\n"
207" NonGRDChi6\n"
208" NonGRDChi6L\n"
209" NonGRDChi7\n"
210"--higher-modes VALUE specify l modes with value 'VALUE' (L2 or RESTRICTED is default)\n"
211"--outname FNAME Output to file FNAME (default 'simulation.dat')\n"
212"--verbose If included, add verbose output\n"
213"--phenomXHMMband float Threshold parameter for the Multibanding of IMRPhenomXHM. By default set to 10^-3. If set to 0 then do not use multibanding.\n"
214"--modesList string List of modes to be used by the model, e.g. --modesList '2,2, 2,-2, 2,1, 2,-1'. \n"
215" To use all the modes available in the mode do not add --modesList. Do not use if you do not know which modes the model returns!\n"
216"--phenomXPHMMband float Threshold parameter for the Multibanding of the Euler angles in IMRPhenomXPHM. \n"
217" Options and default values can be found in https://lscsoft.docs.ligo.org/lalsuite/lalsimulation/group___l_a_l_sim_i_m_r_phenom_x__c.html.\n"
218"--phenomXPHMUseModes int Switch between the two polarization functions IMRPhenomXPHM and IMRPhenomXPHMFromModes.\n"
219" Options and default values can be found in https://lscsoft.docs.ligo.org/lalsuite/lalsimulation/group___l_a_l_sim_i_m_r_phenom_x__c.html.\n"
220"--phenomXPrecVersion int Choose precessing version for the Euler angles.\n"
221" Options and default values can be found in https://lscsoft.docs.ligo.org/lalsuite/lalsimulation/group___l_a_l_sim_i_m_r_phenom_x__c.html.\n"
222"--phenomXPFinalSpinMod int Choose final spin prescription.\n"
223" Options and default values can be found in https://lscsoft.docs.ligo.org/lalsuite/lalsimulation/group___l_a_l_sim_i_m_r_phenom_x__c.html.\n"
224"--newinterface If included, it will use XLALSimInspiralGenerateT(F)DWaveform instead of XLALSimInspiralChooseT(F)DWaveform\n"
225" Can use flexible parameters: --total_mass --chirp_mass --mass_ratio ... --spin1_norm --spin1_tilt --spin1_phi ...\n"
226"--python-module char Name of the External python module\n"
227"--python-object char Name of the python class defined in python-module which includes the methods generate_fd/td_waveform\n"
228;
229
230/* Parse command line, sanity check arguments, and return a newly
231 * allocated GSParams object */
232static GSParams *parse_args(ssize_t argc, char **argv) {
233 ssize_t i;
235 params = (GSParams *) XLALMalloc(sizeof(GSParams));
236 memset(params, 0, sizeof(GSParams));
238 /* Set default values to the arguments */
239 params->approximant = TaylorT1;
243 params->phiRef = 0.;
244 params->deltaT = 1./4096.;
245 params->deltaF = 0.125;
246 params->m1 = 10. * LAL_MSUN_SI;
247 params->m2 = 1.4 * LAL_MSUN_SI;
248 params->f_min = 40.;
249 params->fRef = 0.;
250 params->f_max = 0.; /* Generate as much as possible */
251 params->distance = 100. * 1e6 * LAL_PC_SI;
252 params->inclination = 0.;
253 params->s1x = 0.;
254 params->s1y = 0.;
255 params->s1z = 0.;
256 params->s2x = 0.;
257 params->s2y = 0.;
258 params->s2z = 0.;
259 params->longAscNodes = 0.;
260 params->ecc = 0.;
261 params->meanPerAno = 0.;
262 params->m1_newinterface = 0;
263 params->m2_newinterface = 0;
264 strcpy(params->module, "");
265 strcpy(params->object, "");
268 /* Note: given a LALDict, SEOBNRv2T/v4T will check wether other parameters ( TidalOctupolarLambda, TidalQuadrupolarFMode, TidalOctupolarFMode, dQuadMon) are present in the LALDict */
269 /* If present, this value is looked up and used, if absent, the parameter is computed from quadrupolar lambda through universal relations */
270 /* We therefore do not Insert default values for these parameters, they will be inserted in LALDict only if specified on the commandline */
279 snprintf(params->outname, sizeof(params->outname), "simulation.dat"); /* output to this file */
280 params->verbose = 0; /* No verbosity */
281 /* consume command line */
282 for (i = 1; i < argc; ++i) {
283 if ((strcmp(argv[i], "-h") == 0) || (strcmp(argv[i], "--help") == 0)) {
284 printf("%s", usage);
286 exit(0);
287 } else if (strcmp(argv[i], "--verbose") == 0) {
288 params->verbose = 1;
289 } else if (strcmp(argv[i], "--newinterface") == 0) {
290 params->newinterface = 1;
291 } else if (strcmp(argv[i], "--amp-phase") == 0) {
292 params->ampPhase = 1;
293 } else if ( ( i == argc ) || ( !argv[i+1] ) ) {
294 XLALPrintError("Error: value required for option %s\n", argv[i]);
295 } else if (strcmp(argv[i], "--approximant") == 0) {
296 params->approximant = XLALSimInspiralGetApproximantFromString(argv[++i]);
297 if ( (int) params->approximant == XLAL_FAILURE) {
298 XLALPrintError("Error: invalid value %s for --interaction-flag\n", argv[i]);
299 goto fail;
300 }
301 } else if (strcmp(argv[i], "--domain") == 0) {
302 i++;
303 if (strcmp(argv[i], "TD") == 0)
305 else if (strcmp(argv[i], "FD") == 0)
307 else {
308 XLALPrintError("Error: Unknown domain\n");
309 goto fail;
310 }
311 } else if (strcmp(argv[i], "--phase-order") == 0) {
313 } else if (strcmp(argv[i], "--amp-order") == 0) {
315 } else if (strcmp(argv[i], "--phiRef") == 0) {
316 params->phiRef = atof(argv[++i]);
317 } else if (strcmp(argv[i], "--fRef") == 0) {
318 params->fRef = atof(argv[++i]);
319 } else if (strcmp(argv[i], "--sample-rate") == 0) {
320 params->deltaT = 1./atof(argv[++i]);
321 } else if (strcmp(argv[i], "--deltaF") == 0) {
322 params->deltaF = atof(argv[++i]);
323 } else if (strcmp(argv[i], "--m1") == 0) {
324 params->m1 = atof(argv[++i]) * LAL_MSUN_SI;
325 params->m1_newinterface = 1;
326 } else if (strcmp(argv[i], "--m2") == 0) {
327 params->m2 = atof(argv[++i]) * LAL_MSUN_SI;
328 params->m2_newinterface = 1;
329 } else if (strcmp(argv[i], "--spin1x") == 0) {
330 params->s1x = atof(argv[++i]);
331 } else if (strcmp(argv[i], "--spin1y") == 0) {
332 params->s1y = atof(argv[++i]);
333 } else if (strcmp(argv[i], "--spin1z") == 0) {
334 params->s1z = atof(argv[++i]);
335 } else if (strcmp(argv[i], "--spin2x") == 0) {
336 params->s2x = atof(argv[++i]);
337 } else if (strcmp(argv[i], "--spin2y") == 0) {
338 params->s2y = atof(argv[++i]);
339 } else if (strcmp(argv[i], "--spin2z") == 0) {
340 params->s2z = atof(argv[++i]);
341 } else if (strcmp(argv[i], "--tidal-lambda1") == 0) {
343 } else if (strcmp(argv[i], "--tidal-lambda2") == 0) {
345 } else if (strcmp(argv[i], "--ecc_order") == 0) {
347 } else if (strcmp(argv[i], "--f_ecc") == 0) {
349 } else if (strcmp(argv[i], "--tidal-lambda-octu1") == 0) {
351 } else if (strcmp(argv[i], "--tidal-lambda-octu2") == 0) {
353 } else if (strcmp(argv[i], "--tidal-quadfmode1") == 0) {
355 } else if (strcmp(argv[i], "--tidal-quadfmode2") == 0) {
357 } else if (strcmp(argv[i], "--tidal-octufmode1") == 0) {
359 } else if (strcmp(argv[i], "--tidal-octufmode2") == 0) {
361 } else if (strcmp(argv[i], "--quad-mon1") == 0) {
362 XLALSimInspiralWaveformParamsInsertdQuadMon1(params->params, atof(argv[++i]) - 1.); /* dQuadMon is kappa-1 */
363 } else if (strcmp(argv[i], "--quad-mon2") == 0) {
364 XLALSimInspiralWaveformParamsInsertdQuadMon2(params->params, atof(argv[++i]) - 1.); /* dQuadMon is kappa-1 */
365 } else if (strcmp(argv[i], "--spin-order") == 0) {
367 } else if (strcmp(argv[i], "--tidal-order") == 0) {
369 } else if (strcmp(argv[i], "--f-min") == 0) {
370 params->f_min = atof(argv[++i]);
371 } else if (strcmp(argv[i], "--f-max") == 0) {
372 params->f_max = atof(argv[++i]);
373 } else if (strcmp(argv[i], "--distance") == 0) {
374 params->distance = atof(argv[++i]) * 1e6 * LAL_PC_SI;
375 } else if (strcmp(argv[i], "--inclination") == 0) {
376 params->inclination = atof(argv[++i]);
377 } else if (strcmp(argv[i], "--long-asc-nodes") == 0) {
378 params->longAscNodes = atof(argv[++i]);
379 } else if (strcmp(argv[i], "--eccentricity") == 0) {
380 params->ecc = atof(argv[++i]);
381 } else if (strcmp(argv[i], "--mean-per-ano") == 0) {
382 params->meanPerAno = atof(argv[++i]);
383 } else if (strcmp(argv[i], "--axis") == 0) {
386 == (int) XLAL_FAILURE) {
387 XLALPrintError("Error: invalid value %s for --axis\n", argv[i]);
388 goto fail;
389 }
390 } else if (strcmp(argv[i], "--modes") == 0) {
393 XLALPrintError("Error: invalid value %s for --modes\n", argv[i]);
394 goto fail;
395 }
396 } else if (strcmp(argv[i], "--nonGRpar") == 0) {
397 char name[100];
398 strcpy(name,argv[++i]);
399 if ( ( i == argc ) || ( !argv[i+1] ) ) {
400 XLALPrintError("Error: 'name value' pair required for option %s\n", argv[i-1]);
401 } else if(strcmp(name,"Phi1")==0) {
403 }
404 } else if (strcmp(argv[i], "--outname") == 0) {
405 snprintf(params->outname, sizeof(params->outname), "%s", argv[++i]);
406 } else if (strcmp(argv[i], "--nr-file") == 0) {
408 } else if (strcmp(argv[i], "--modesList") == 0) {
409 char *current_mode;
410 int modes[50], iii = 0;
411 while ((current_mode = strtok(iii ? NULL : argv[++i], ",")) != NULL){
412 modes[iii++] = atoi(current_mode);
413 }
414 LALValue *ModeArray = XLALSimInspiralCreateModeArray();
415 for (int ii=0; ii<iii; ii+=2){
416 XLALSimInspiralModeArrayActivateMode(ModeArray, modes[ii], modes[ii+1]);
418 }
419 XLALDestroyValue(ModeArray);
420
421 }else if(strcmp(argv[i], "--phenomXHMMband") == 0){
423 }else if(strcmp(argv[i], "--phenomXPHMMband") == 0){
425 }else if(strcmp(argv[i], "--phenomXPHMUseModes") == 0){
427 }else if(strcmp(argv[i], "--phenomXPrecVersion") == 0){
429 }else if(strcmp(argv[i], "--phenomXPFinalSpinMod") == 0){
431 }else if(strcmp(argv[i], "--phenomXHMRelease") == 0){
433 /* New interface specific */
434 } else if (strcmp(argv[i], "--total_mass") == 0) {
436 } else if (strcmp(argv[i], "--chirp_mass") == 0) {
438 } else if (strcmp(argv[i], "--mass_difference") == 0) {
440 } else if (strcmp(argv[i], "--reduced_mass") == 0) {
442 } else if (strcmp(argv[i], "--spin1_norm") == 0) {
444 } else if (strcmp(argv[i], "--spin1_tilt") == 0) {
446 } else if (strcmp(argv[i], "--spin1_phi") == 0) {
448 } else if (strcmp(argv[i], "--spin2_norm") == 0) {
450 } else if (strcmp(argv[i], "--spin2_tilt") == 0) {
452 } else if (strcmp(argv[i], "--spin2_phi") == 0) {
454 } else if (strcmp(argv[i], "--condition") == 0) {
455 params->condition = atoi(argv[++i]);
456 } else if (strcmp(argv[i], "--python-module") == 0) {
457 snprintf(params->module, sizeof(params->module), "%s", argv[++i]);
458 } else if (strcmp(argv[i], "--python-object") == 0) {
459 snprintf(params->object, sizeof(params->object), "%s", argv[++i]);
460 }else {
461 XLALPrintError("Error: invalid option: %s\n", argv[i]);
462 goto fail;
463 }
464 }
465
466 return params;
467
468 fail:
469 printf("%s", usage);
471 exit(1);
472}
473
474/* Function to "unwind" a phase variable with a branch cut */
475static int unwind_phase(REAL8 phiUW[], REAL8 phi[],
476 size_t len, REAL8 thresh) {
477 int cnt = 0; // # of times wrapped around branch cut
478 size_t i;
479 phiUW[0] = phi[0];
480 for(i=1; i<len; i++) {
481 if(phi[i-1] - phi[i] > thresh) // phase wrapped forward
482 cnt += 1;
483 else if(phi[i] - phi[i-1] > thresh) // phase wrapped backwards
484 cnt -= 1;
485 phiUW[i] = phi[i] + cnt * LAL_TWOPI;
486 }
487 return 0;
488}
489
490static int dump_FD(FILE *f, COMPLEX16FrequencySeries *hptilde,
491 COMPLEX16FrequencySeries *hctilde) {
492 size_t i;
493 COMPLEX16 *dataPtr1 = hptilde->data->data;
494 COMPLEX16 *dataPtr2 = hctilde->data->data;
495 if (hptilde->data->length != hctilde->data->length) {
496 XLALPrintError("Error: hptilde and hctilde are not the same length\n");
497 return 1;
498 } else if (hptilde->deltaF != hctilde->deltaF) {
499 XLALPrintError("Error: hptilde and hctilde do not have the same freq. bin size\n");
500 return 1;
501 }
502
503 fprintf(f, "# f hptilde.re hptilde.im hctilde.re hctilde.im\n");
504 for (i=0; i < hptilde->data->length; i++)
505 fprintf(f, "%.16e %.16e %.16e %.16e %.16e\n",
506 hptilde->f0 + i * hptilde->deltaF,
507 creal(dataPtr1[i]), cimag(dataPtr1[i]), creal(dataPtr2[i]), cimag(dataPtr2[i]));
508 return 0;
509}
510
511static int dump_FD2(FILE *f, COMPLEX16FrequencySeries *hptilde,
512 COMPLEX16FrequencySeries *hctilde) {
513 size_t i;
514 REAL8 threshold=5.; // Threshold to determine phase wrap-around
515 COMPLEX16 *dataPtr1 = hptilde->data->data;
516 COMPLEX16 *dataPtr2 = hctilde->data->data;
517 if (hptilde->data->length != hctilde->data->length) {
518 XLALPrintError("Error: hptilde and hctilde are not the same length\n");
519 return 1;
520 } else if (hptilde->deltaF != hctilde->deltaF) {
521 XLALPrintError("Error: hptilde and hctilde do not have the same freq. bin size\n");
522 return 1;
523 }
524 REAL8 amp1[hptilde->data->length], amp2[hptilde->data->length];
525 REAL8 phase1[hptilde->data->length], phase2[hptilde->data->length];
526 REAL8 phaseUW1[hptilde->data->length], phaseUW2[hptilde->data->length];
527 for (i=0; i < hptilde->data->length; i++)
528 {
529 amp1[i] = sqrt(creal(dataPtr1[i])*creal(dataPtr1[i])
530 + cimag(dataPtr1[i])*cimag(dataPtr1[i]));
531 phase1[i] = atan2(cimag(dataPtr1[i]), creal(dataPtr1[i]));
532 amp2[i] = sqrt(creal(dataPtr2[i])*creal(dataPtr2[i])
533 + cimag(dataPtr2[i])*cimag(dataPtr2[i]));
534 phase2[i] = atan2(cimag(dataPtr2[i]), creal(dataPtr2[i]));
535 }
536 unwind_phase(phaseUW1, phase1, hptilde->data->length, threshold);
537 unwind_phase(phaseUW2, phase2, hptilde->data->length, threshold);
538
539 fprintf(f, "# f amp_+ phase_+ amp_x phase_x\n");
540 for (i=0; i < hptilde->data->length; i++)
541 fprintf(f, "%25.16e %25.16e %25.16e %25.16e %25.16e\n",
542 hptilde->f0 + i * hptilde->deltaF,
543 amp1[i], phaseUW1[i], amp2[i], phaseUW2[i]);
544 return 0;
545}
546
547static int dump_TD(FILE *f, REAL8TimeSeries *hplus, REAL8TimeSeries *hcross) {
548 size_t i;
549 REAL8 t0 = XLALGPSGetREAL8(&(hplus->epoch));
550 if (hplus->data->length != hcross->data->length) {
551 XLALPrintError("Error: hplus and hcross are not the same length\n");
552 return 1;
553 } else if (hplus->deltaT != hcross->deltaT) {
554 XLALPrintError("Error: hplus and hcross do not have the same sample rate\n");
555 return 1;
556 }
557
558 fprintf(f, "# t hplus hcross\n");
559 for (i=0; i < hplus->data->length; i++)
560 fprintf(f, "%25.16e %25.16e %25.16e\n", t0 + i * hplus->deltaT,
561 hplus->data->data[i], hcross->data->data[i]);
562 return 0;
563}
564
565static int dump_TD2(FILE *f, REAL8TimeSeries *hplus, REAL8TimeSeries *hcross) {
566 size_t i;
567 REAL8 t0 = XLALGPSGetREAL8(&(hplus->epoch));
568 REAL8 threshold=5.; // Threshold to determine phase wrap-around
569 REAL8 *dataPtr1 = hplus->data->data;
570 REAL8 *dataPtr2 = hcross->data->data;
571 if (hplus->data->length != hcross->data->length) {
572 XLALPrintError("Error: hplus and hcross are not the same length\n");
573 return 1;
574 } else if (hplus->deltaT != hcross->deltaT) {
575 XLALPrintError("Error: hplus and hcross do not have the same sample rate\n");
576 return 1;
577 }
578 REAL8 amp[hplus->data->length];
579 REAL8 phase[hplus->data->length];
580 REAL8 phaseUW[hplus->data->length];
581 for (i=0; i < hplus->data->length; i++)
582 {
583 amp[i] = sqrt( dataPtr1[i]*dataPtr1[i] + dataPtr2[i]*dataPtr2[i]);
584 phase[i] = atan2(-dataPtr2[i], dataPtr1[i]);
585 }
586 unwind_phase(phaseUW, phase, hplus->data->length, threshold);
587
588 fprintf(f, "# t amp phase\n");
589 for (i=0; i < hplus->data->length; i++)
590 fprintf(f, "%25.16e %25.16e %25.16e\n", t0 + i * hplus->deltaT,
591 amp[i], phaseUW[i]);
592 return 0;
593}
594
595/*
596 * main
597 */
598int main (int argc , char **argv) {
599 FILE *f;
600 int status;
601 int start_time;
602 COMPLEX16FrequencySeries *hptilde = NULL, *hctilde = NULL;
603 REAL8TimeSeries *hplus = NULL;
604 REAL8TimeSeries *hcross = NULL;
606
607 /* set us up to fail hard */
609
610 /* parse commandline */
611 params = parse_args(argc, argv);
612
613 /* generate waveform */
614 start_time = time(NULL);
615 if (params->newinterface == 0) // Use old interface
616 {
617 switch (params->domain) {
619 XLALSimInspiralChooseFDWaveform(&hptilde, &hctilde,
624 params->deltaF, params->f_min, params->f_max, params->fRef,
625 params->params, params->approximant);
626 break;
628 XLALSimInspiralChooseTDWaveform(&hplus, &hcross,
633 params->deltaT, params->f_min, params->fRef,
634 params->params,
635 params->approximant);
636 break;
637 default:
638 XLALPrintError("Error: domain must be either TD or FD\n");
639 }
640 }
641 else // Use new interface
642 {
643 /* Generator */
644 LALDict *generator_params = XLALCreateDict();
645 if (params->condition){
646 XLALDictInsertINT4Value(generator_params, "condition", params->condition);
647 }
648 if (strcmp(params->module, "") != 0){
649 XLALDictInsertStringValue(generator_params, "module", params->module);
650 }
651 if (strcmp(params->object, "") != 0){
652 XLALDictInsertStringValue(generator_params, "object", params->object);
653 XLALDictInsertINT4Value(generator_params, "approximant", IMRPhenomXPHM);
654 }
655 LALSimInspiralGenerator *generator = XLALSimInspiralChooseGenerator(params->approximant, generator_params);
656 XLAL_CHECK(generator, XLAL_EFUNC);
657
658 /* Parse waveform params into laldictionary */
659 /* If none of the optional mass arguments are used, we use the component masses which are stored in the params object */
660 const char *mass_keys[6] = {"total_mass", "chirp_mass", "mass_difference", "reduced_mass", "mass_ratio", "sym_mass_ratio"};
661 UINT2 key_exists = 0;
662 for (size_t j = 0; j < sizeof(mass_keys)/sizeof(*mass_keys); ++j){
663 if (XLALDictContains(params->params, mass_keys[j]) == 1) {
664 key_exists = 1;
665 break;
666 }
667 }
668 if (key_exists == 0){
671 }
672 else{
673 /* Insert component masses if they are in the command line */
676 }
677 /* If any of the optional spin arguments are used, we use the cartesian spins which are stored in the params object */
678 if (XLALDictContains(params->params, "spin1_norm") == 0 && XLALDictContains(params->params, "spin1_tilt") == 0 && XLALDictContains(params->params, "spin1_phi") == 0){
682 }
683 if (XLALDictContains(params->params, "spin2_norm") == 0 && XLALDictContains(params->params, "spin2_tilt") == 0 && XLALDictContains(params->params, "spin2_phi") == 0){
687 }
688 /* Insert the rest of waveform params */
700
701 /* generate waveform */
702 switch (params->domain) {
704 XLALSimInspiralGenerateFDWaveform(&hptilde, &hctilde, params->params, generator);
705 break;
707 XLALSimInspiralGenerateTDWaveform(&hplus, &hcross, params->params, generator);
708 break;
709 default:
710 XLALPrintError("Error: domain must be either TD or FD\n");
711 }
712 XLALDestroyDict(generator_params);
714 }
715 if (params->verbose)
716 XLALPrintInfo("Generation took %.0f seconds\n",
717 difftime(time(NULL), start_time));
718 if (((params->domain == LAL_SIM_DOMAIN_FREQUENCY) && (!hptilde || !hctilde)) ||
719 ((params->domain == LAL_SIM_DOMAIN_TIME) && (!hplus || !hcross))) {
720 XLALPrintError("Error: waveform generation failed\n");
721 goto fail;
722 }
723
724 /* dump file */
725 if ( strlen(params->outname) > 0 ) {
726 f = fopen(params->outname, "w");
727 if (f==NULL) {
728 printf("**ERROR** Impossible to write file %s\n",params->outname);
729 exit(1);
730 }
731 else {
733 if (params->ampPhase == 1)
734 status = dump_FD2(f, hptilde, hctilde);
735 else
736 status = dump_FD(f, hptilde, hctilde);
737 else
738 if (params->ampPhase == 1)
739 status = dump_TD2(f, hplus, hcross);
740 else
741 status = dump_TD(f, hplus, hcross);
742 fclose(f);
743 }
744 if (status) goto fail;
745 }
746
747 /* clean up */
752
755 return 0;
756
757 fail:
762 return 1;
763}
static int dump_TD2(FILE *f, REAL8TimeSeries *hplus, REAL8TimeSeries *hcross)
static int dump_FD2(FILE *f, COMPLEX16FrequencySeries *hptilde, COMPLEX16FrequencySeries *hctilde)
int main(int argc, char **argv)
static int dump_FD(FILE *f, COMPLEX16FrequencySeries *hptilde, COMPLEX16FrequencySeries *hctilde)
static int dump_TD(FILE *f, REAL8TimeSeries *hplus, REAL8TimeSeries *hcross)
static GSParams * parse_args(ssize_t argc, char **argv)
const char * usage
static int unwind_phase(REAL8 phiUW[], REAL8 phi[], size_t len, REAL8 thresh)
int XLALDictContains(const LALDict *dict, const char *key)
void XLALDestroyDict(LALDict *dict)
LALDict * XLALCreateDict(void)
int XLALDictInsertStringValue(LALDict *dict, const char *key, const char *string)
int XLALDictInsertINT4Value(LALDict *dict, const char *key, INT4 value)
int XLALSimInspiralGetHigherModesFromString(const char *string)
Parses a string to determine the LALSimInspiralModesChoice enum value.
int XLALGetFrameAxisFromString(const char *waveform)
int XLALSimInspiralGetApproximantFromString(const char *waveform)
Parses a waveform string to determine approximant.
int XLALSimInspiralWaveformParamsInsertModeArray(LALDict *params, LALValue *value)
int XLALSimInspiralWaveformParamsInsertSpin1z(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertMass1(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertF22Ref(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertSpin2tilt(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertTidalQuadrupolarFMode1(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPNPhaseOrder(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertNumRelData(LALDict *params, const char *value)
int XLALSimInspiralWaveformParamsInsertDeltaF(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertEccentricityFreq(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertLongAscNodes(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertSpin1tilt(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertSpin2z(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertRefPhase(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPhenomXPHMThresholdMband(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertSpin1y(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertMeanPerAno(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertTidalLambda1(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertEccentricity(LALDict *params, REAL8 value)
INT4 XLALSimInspiralWaveformParamsLookupFrameAxis(LALDict *params)
int XLALSimInspiralWaveformParamsInsertTidalOctupolarFMode1(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertModesChoice(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertSpin1norm(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPhenomXHMThresholdMband(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertInclination(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertDeltaT(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertTidalOctupolarLambda1(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertTidalOctupolarFMode2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertFrameAxis(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertSpin2phi(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPhenomXPFinalSpinMod(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertPNEccentricityOrder(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertReducedMass(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPhenomXHMReleaseVersion(LALDict *params, INT4 value)
INT4 XLALSimInspiralWaveformParamsLookupModesChoice(LALDict *params)
int XLALSimInspiralWaveformParamsInsertPNSpinOrder(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertSpin2x(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertTidalLambda2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPNAmplitudeOrder(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertF22Start(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertdQuadMon2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertTidalOctupolarLambda2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertTidalQuadrupolarFMode2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPNTidalOrder(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertSpin1phi(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertdQuadMon1(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertNonGRPhi1(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertSpin2y(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertSpin1x(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertPhenomXPrecVersion(LALDict *params, INT4 value)
int XLALSimInspiralWaveformParamsInsertChirpMass(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertSpin2norm(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertFMax(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertTotalMass(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertMassDifference(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertMass2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertDistance(LALDict *params, REAL8 value)
const char * name
void XLALDestroyValue(LALValue *value)
#define fprintf
double i
Definition: bh_ringdown.c:118
void XLALDestroyCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series)
#define LAL_MSUN_SI
#define LAL_TWOPI
#define LAL_PC_SI
double complex COMPLEX16
double REAL8
uint16_t UINT2
void * XLALMalloc(size_t n)
void XLALFree(void *p)
int XLALSimInspiralGenerateTDWaveform(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, LALDict *params, LALSimInspiralGenerator *generator)
Returns time-domain polarizations for a specific approximant.
int XLALSimInspiralGenerateFDWaveform(COMPLEX16FrequencySeries **hplus, COMPLEX16FrequencySeries **hcross, LALDict *params, LALSimInspiralGenerator *generator)
Returns frequency-domain polarizations for a specific approximant.
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...
LALSimInspiralGenerator * XLALSimInspiralChooseGenerator(Approximant approx, LALDict *params)
Returns LALSimInspiralGenerator object from approximant.
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...
void XLALDestroySimInspiralGenerator(LALSimInspiralGenerator *generator)
Destroy LALSimInspiralGenerator object.
LALSimulationDomain
Enumeration to specify time or frequency domain.
Approximant
Enum that specifies the PN approximant to be used in computing the waveform.
@ LAL_SIM_DOMAIN_TIME
@ LAL_SIM_DOMAIN_FREQUENCY
@ IMRPhenomXPHM
Frequency domain, precessing with subdominant modes phenomenological IMR waveform model.
@ TaylorT1
Time domain Taylor approximant in which the energy and flux are both kept as Taylor expansions and a ...
LALValue * XLALSimInspiralModeArrayActivateMode(LALValue *modes, unsigned l, int m)
LALValue * XLALSimInspiralCreateModeArray(void)
Create a LALValue pointer to store the mode array.
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
void XLALAbortErrorHandler(const char *func, const char *file, int line, int errnum)
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLALErrorHandlerType * XLALSetErrorHandler(XLALErrorHandlerType *newHandler)
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
XLAL_EFUNC
XLAL_FAILURE
REAL8 XLALGPSGetREAL8(const LIGOTimeGPS *epoch)
string status
COMPLEX16Sequence * data
COMPLEX16 * data
char module[256]
Name of the External python module.
REAL8 phiRef
phase at fRef
int condition
Conditioning waveform for (Inverse)Fourier Transform.
REAL8 s2y
z-axis along line of sight, L in x-z plane
REAL8 f_min
start frequency
REAL8 inclination
inclination of L relative to line of sight
REAL8 s1x
(x,y,z) components of spin of m1 body
REAL8 fRef
reference frequency
REAL8 s1y
z-axis along line of sight, L in x-z plane
REAL8 deltaF
frequency resolution
REAL8 deltaT
sampling interval
Approximant approximant
waveform family or "approximant"
REAL8 meanPerAno
mean periastron anomaly 0<= psi < 2 Pi
REAL8 s2x
(x,y,z) component ofs spin of m2 body
int m2_newinterface
Check if mass2 is an input argument.
int newinterface
0 or 1: Old or New interface respectively
REAL8 s2z
dimensionless spin, Kerr bound: |s2| <= 1
LALSimulationDomain domain
flag for time or frequency domain waveform
LALDict * params
Container for all accessory parameters.
REAL8 m2
mass of companion 2
REAL8 m1
mass of companion 1
int m1_newinterface
Check if mass1 is an input argument.
REAL8 distance
distance of source
REAL8 s1z
dimensionless spin, Kerr bound: |s1| <= 1
REAL8 f_max
end frequency
char outname[256]
file to which output should be written
REAL8 longAscNodes
longitude of ascending nodes 0<= omega < 2 pi
REAL8 ecc
eccentricity 0<= ecc < 1
REAL8Sequence * data
LIGOTimeGPS epoch
REAL8 * data
Definition: burst.c:245
double meanPerAno
Definition: inspiral.c:232
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 m2
Definition: inspiral.c:238
int condition
Definition: inspiral.c:227
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