LALSimulation  5.4.0.1-b72065a
LALSimInspiral.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008 J. Creighton, S. Fairhurst, B. Krishnan, L. Santamaria, D. Keppel, Evan Ochsner, C. Pankow, 2014 A. Klein
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 <complex.h>
21 #include <math.h>
22 
23 #include <gsl/gsl_const.h>
24 #include <gsl/gsl_errno.h>
25 #include <gsl/gsl_math.h>
26 #include <gsl/gsl_odeiv.h>
27 
28 #include <lal/SphericalHarmonics.h>
29 #include <lal/LALSimInspiral.h>
30 #include <lal/LALSimInspiralEOS.h>
31 #include <lal/LALSimIMR.h>
32 #include <lal/LALSimSphHarmMode.h>
33 #include <lal/LALConstants.h>
34 #include <lal/LALStdlib.h>
35 #include <lal/LALString.h>
36 #include <lal/Sequence.h>
37 #include <lal/TimeSeries.h>
38 #include <lal/FrequencySeries.h>
39 #include <lal/TimeFreqFFT.h>
40 #include <lal/BandPassTimeSeries.h>
41 #include <lal/Units.h>
42 #include <lal/LALSimBlackHoleRingdown.h>
43 #include <lal/LALSimInspiralPrecess.h>
44 #include <lal/LALSimInspiralWaveformParams.h>
45 
47 #include "check_series_macros.h"
48 #include "check_waveform_macros.h"
50 #include "rotation_macros.h"
52 
54 
55 #ifdef __GNUC__
56 #define UNUSED __attribute__ ((unused))
57 #else
58 #define UNUSED
59 #endif
60 
61 /**
62  * (Twice) the highest known PN order of amplitude correction for
63  * non-precessing binaries.
64  */
65 #define MAX_NONPRECESSING_AMP_PN_ORDER 6
66 
67 /**
68  * (Twice) the highest known PN order of amplitude correction for
69  * precessing binaries.
70  */
71 #define MAX_PRECESSING_AMP_PN_ORDER 3
72 
73 
74 
75 
76 #define INITIALIZE_NAME(a) [a] = #a
77 /* TODO: UPDATE ME WHENEVER A NEW APPROXIMANT IS ADDED */
78 static const char *lalSimulationApproximantNames[] = {
193 };
194 #undef INITIALIZE_NAME
195 
196 /* TODO: UPDATE ME WHENEVER A NEW PN ORDER IS ADDED */
197 static const char *lalSimulationPNOrderNames[] = {
198  [LAL_PNORDER_NEWTONIAN] = "newtonian",
199  [LAL_PNORDER_HALF] = "oneHalfPN",
200  [LAL_PNORDER_ONE] = "onePN",
201  [LAL_PNORDER_ONE_POINT_FIVE] = "onePointFivePN",
202  [LAL_PNORDER_TWO] = "twoPN",
203  [LAL_PNORDER_TWO_POINT_FIVE] = "twoPointFivePN",
204  [LAL_PNORDER_THREE] = "threePN",
205  [LAL_PNORDER_THREE_POINT_FIVE] = "threePointFivePN",
206  [LAL_PNORDER_PSEUDO_FOUR] = "pseudoFourPN",
207 };
208 
209 /* TODO: UPDATE ME WHENEVER A NEW TAPER IS ADDED */
210 static const char *lalSimulationTaperNames[] = {
211  [LAL_SIM_INSPIRAL_TAPER_NONE] = "TAPER_NONE",
212  [LAL_SIM_INSPIRAL_TAPER_START] = "TAPER_START",
213  [LAL_SIM_INSPIRAL_TAPER_END] = "TAPER_END",
214  [LAL_SIM_INSPIRAL_TAPER_STARTEND] = "TAPER_STARTEND",
215 };
216 
217 /* TODO: UPDATE ME WHENEVER A NEW FRAME AXIS IS ADDED */
218 static const char *lalSimulationFrameAxisNames[] = {
222 };
223 
224 /* TODO: UPDATE ME WHENEVER A NEW MODES CHOICE IS ADDED */
225 static const char *lalSimulationModesChoiceNames[] = {
237  [LAL_SIM_INSPIRAL_MODES_CHOICE_RESTRICTED] = "L2",
241  /* NOTE: cannot do the "ALL" case since its value is -1 */
242  // [LAL_SIM_INSPIRAL_MODES_CHOICE_ALL] = "ALL",
243 };
244 
245 /* locates and deletes a substring in a list of substrings from a string, ignoring case;
246  * if multiple substrings in the string match, delete the longest one; here, deletion
247  * means replacing the substring with BEL characters */
248 static int delete_substring_in_list_from_string(char *string, const char *list[], size_t size)
249 {
250  int longest_position = -1;
251  int longest_offset = -1;
252  int longest_length = -1;
253  size_t i;
254 
255  if (string == NULL || strlen(string) == 0) // no string to search
256  return -1;
257 
258  for (i = 0; i < size; ++i) {
259  char *match;
260  if (list[i] == NULL) // no such element in list
261  continue;
262  if ((match = XLALStringCaseSubstring(string, list[i]))) {
263  int length = strlen(list[i]);
264  if (length > longest_length) {
265  longest_position = i;
266  longest_offset = match - string;
267  longest_length = length;
268  }
269  }
270  }
271 
272  if (longest_position < 0) // failed to find a word
273  return -1;
274 
275  /* delete word from string by replacing with BEL */
276  for (i = 0; i < (size_t)longest_length; ++i)
277  string[longest_offset + i] = '\b';
278 
279  return longest_position;
280 }
281 
282 const LALSimInspiralGenerator *lalSimInspiralGeneratorTemplates[NumApproximants] = {
373 };
374 
375 /**
376  * @addtogroup LALSimInspiral_c
377  * @brief General routines for generating binary inspiral waveforms.
378  *
379  * @{
380  */
381 
382  /**
383  * @name New Interface Generator Routines
384  * @{
385  */
386 
387  /**
388  * Destroy LALSimInspiralGenerator object.
389  */
390 void XLALDestroySimInspiralGenerator(LALSimInspiralGenerator *generator)
391 {
392  if (generator) {
393  if (generator->initialize == NULL && generator->finalize == NULL) {
394  /* assume generator is immutable -- this is a no-op */
395  return;
396  }
397  /* invoke finalizer if present */
398  if (generator->finalize)
399  if (generator->finalize(generator) < 0)
401  XLALFree(generator);
402  }
403  return;
404 }
405 
406 /**
407  * Create LALSimInspiralGenerator object.
408  * The LALDict can be None for all the C approximants. For external python model, the LALDict must contain the file and class object where the `generate_waveform` methods are defined.
409  * Activating the option `condition` in the LALDict will generate the waveform with adequate conditioning for (inverse)Fourier transform.
410  */
411 LALSimInspiralGenerator *XLALCreateSimInspiralGenerator(const LALSimInspiralGenerator *generator, LALDict *params)
412 {
413  LALSimInspiralGenerator *new;
414  XLAL_CHECK_NULL(generator, XLAL_EFAULT);
415  if (generator->initialize == NULL && generator->finalize == NULL) {
416  /* assume generator is immutable -- return the template */
417  /* danger! discard the const qualifier! */
418  new = (LALSimInspiralGenerator *)(intptr_t)generator;
419  } else {
420  /* create a new instance of the generator */
421  new = XLALMalloc(sizeof(*new));
422  XLAL_CHECK_NULL(new, XLAL_ENOMEM, "could not allocate memory for new generator");
423  memcpy(new, generator, sizeof(*new));
424  /* invoke initializer if present */
425  if (new->initialize)
426  if (new->initialize(new, params) < 0) {
427  XLALFree(new);
429  }
430  }
431  return new;
432 }
433 
434 /**
435  * Returns LALSimInspiralGenerator object from approximant.
436  * The LALDict can be None for all the C approximants. For external python model, the LALDict must contain the file and class object where the `generate_waveform` methods are defined.
437  * Activating the option `condition` in the LALDict will generate the waveform with adequate conditioning for (inverse)Fourier transform.
438  */
439 LALSimInspiralGenerator *XLALSimInspiralChooseGenerator(Approximant approx, LALDict *params)
440 {
441  const LALSimInspiralGenerator *template = lalSimInspiralGeneratorTemplates[approx];
442  XLAL_CHECK_NULL(template, XLAL_EINVAL, "no generator defined for approximant %d", approx);
443  return XLALCreateSimInspiralGenerator(template, params);
444 }
445 
446 /**
447  * Return approximant name from generator object
448  *
449  */
450 const char *XLALSimInspiralGeneratorName(LALSimInspiralGenerator *generator)
451 {
452  XLAL_CHECK_NULL(generator, XLAL_EFAULT);
453  return generator->name;
454 }
455 
456  /** @} */
457 
458 /**
459  * @name New Interface Waveform Routines
460  * @{
461  */
462 
463 /**
464  * Returns time-domain polarizations for a specific approximant.
465  * Equivalent to XLALSimInspiralChooseTDWaveform(). Equivalent to XLALSimInspiralTD() if the option `condition` is activated in the LALDict.
466  * The waveform arguments are inserted into the LALDict. The generator carries the info about the approximant and potentially extra data which could be recycled by the model to speed-up calculation.
467  *
468  * The parameters in the LALDict must be in SI units.
469  */
471  REAL8TimeSeries **hplus,
472  REAL8TimeSeries **hcross,
473  LALDict *params,
474  LALSimInspiralGenerator *generator
475 )
476 {
477  XLAL_CHECK(hplus && hcross && generator, XLAL_EFAULT);
478  XLAL_CHECK(*hplus == NULL && *hcross == NULL, XLAL_EINVAL, "hplus and hcross must be pointers to NULL");
479 
480  if (generator->generate_td_waveform)
481  return generator->generate_td_waveform(hplus, hcross, params, generator);
482 
483  XLAL_ERROR(XLAL_EINVAL, "generator does not provide a method to generate time-domain waveforms");
484 }
485 
486 /**
487  * Compute time-domain modes for a specific approximant.
488  * Equivalent to XLALSimInspiralChooseTDModes(). The only difference is that the SphHarmSeries object needs to be passed as an argument to the function. The actual returned value is an integer which indicates success or error in the waveform evaluation (see https://lscsoft.docs.ligo.org/lalsuite/lal/group___x_l_a_l_error__h.html).
489  * The waveform arguments are inserted into the LALDict. The generator carries the info about the approximant and potentially extra data which could be recycled by the model to speed-up calculation.
490  *
491  * The parameters in the LALDict must be in SI units.
492  */
494  SphHarmTimeSeries **hlm,
495  LALDict *params,
496  LALSimInspiralGenerator *generator
497 )
498 {
499  XLAL_CHECK(hlm && generator, XLAL_EFAULT);
500  XLAL_CHECK(*hlm == NULL, XLAL_EINVAL, "hlm must be a pointer to NULL");
501 
502  if (generator->generate_td_modes)
503  return generator->generate_td_modes(hlm, params, generator);
504 
505  XLAL_ERROR(XLAL_EINVAL, "generator does not provide a method to generate time-domain modes");
506 }
507 
508 /**
509  * Returns frequency-domain polarizations for a specific approximant.
510  * Equivalent to XLALSimInspiralChooseFDWaveform(). Equivalent to XLALSimInspiralFD() if the option `condition` is activated in the LALDict.
511  * The waveform arguments are inserted into the LALDict. The generator carries the info about the approximant and potentially extra data which could be recycled by the model to speed-up calculation.
512  *
513  * The parameters in the LALDict must be in SI units.
514  */
516  COMPLEX16FrequencySeries **hplus,
517  COMPLEX16FrequencySeries **hcross,
518  LALDict *params,
519  LALSimInspiralGenerator *generator
520 )
521 {
522  XLAL_CHECK(hplus && hcross && generator, XLAL_EFAULT);
523  XLAL_CHECK(*hplus == NULL && *hcross == NULL, XLAL_EINVAL, "hplus and hcross must be pointers to NULL");
524  if (generator->generate_fd_waveform)
525  return generator->generate_fd_waveform(hplus, hcross, params, generator);
526 
527  XLAL_ERROR(XLAL_EINVAL, "generator does not provide a method to generate frequency-domain waveforms");
528 }
529 
530 /**
531  * Compute frequency-domain modes for a specific approximant.
532  * Equivalent to XLALSimInspiralChooseFDModes. The only difference is that the SphHarmSeries object needs to be passed as an argument to the function. The actual returned value is an integer which indicates success or error in the waveform evaluation (see https://lscsoft.docs.ligo.org/lalsuite/lal/group___x_l_a_l_error__h.html).
533  * The waveform arguments are inserted into the LALDict. The generator carries the info about the approximant and potentially extra data which could be recycled by the model to speed-up calculation.
534  *
535  * The parameters in the LALDict must be in SI units.
536  */
539  LALDict *params,
540  LALSimInspiralGenerator *generator
541 )
542 {
543  XLAL_CHECK(hlm && generator, XLAL_EFAULT);
544  XLAL_CHECK(*hlm == NULL, XLAL_EINVAL, "hlm must be a pointer to NULL");
545 
546  if (generator->generate_fd_modes)
547  return generator->generate_fd_modes(hlm, params, generator);
548 
549  XLAL_ERROR(XLAL_EINVAL, "generator does not provide a method to generate frequency-domain modes");
550 }
551 
552 /** @} */
553 
554 /**
555 * @name New Interface parse parameters Routines
556 * @{
557 */
558 
559 /**
560  * Insert all the input arguments needed by XALSimInspiralChooseTDWaveform() into a laldictionary.
561  */
563  REAL8 *m1, /**< [out] mass of companion 1 (kg) */
564  REAL8 *m2, /**< [out] mass of companion 2 (kg) */
565  REAL8 *S1x, /**< [out] x-component of the dimensionless spin of object 1 */
566  REAL8 *S1y, /**< [out] y-component of the dimensionless spin of object 1 */
567  REAL8 *S1z, /**< [out] z-component of the dimensionless spin of object 1 */
568  REAL8 *S2x, /**< [out] x-component of the dimensionless spin of object 2 */
569  REAL8 *S2y, /**< [out] y-component of the dimensionless spin of object 2 */
570  REAL8 *S2z, /**< [out] z-component of the dimensionless spin of object 2 */
571  REAL8 *distance, /**< [out] distance of source (m) */
572  REAL8 *inclination, /**< [out] inclination of source (rad) */
573  REAL8 *phiRef, /**< [out] reference orbital phase (rad) */
574  REAL8 *longAscNodes, /**< [out] longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
575  REAL8 *eccentricity, /**< [out] eccentrocity at reference epoch */
576  REAL8 *meanPerAno, /**< [out] mean anomaly of periastron */
577  REAL8 *deltaT, /**< [out] sampling interval (s) */
578  REAL8 *f_min, /**< [out] starting GW frequency (Hz) */
579  REAL8 *f_ref, /**< [out] reference frequency (Hz) */
580  LALDict *params /**< Input lal dictionary with waveform (and optional) parameters **/
581 )
582 {
600 
601  return;
602 }
603 
604 /**
605  * Insert all the input arguments needed by XLALSimInspiralChooseTDModes() into a laldictionary.
606  */
608  REAL8 *phiRef, /**< [out] reference orbital phase (rad) */
609  REAL8 *deltaT, /**< [out] sampling interval (s) */
610  REAL8 *m1, /**< [out] mass of companion 1 (kg) */
611  REAL8 *m2, /**< [out] mass of companion 2 (kg) */
612  REAL8 *S1x, /**< [out] x-component of the dimensionless spin of object 1 */
613  REAL8 *S1y, /**< [out] y-component of the dimensionless spin of object 1 */
614  REAL8 *S1z, /**< [out] z-component of the dimensionless spin of object 1 */
615  REAL8 *S2x, /**< [out] x-component of the dimensionless spin of object 2 */
616  REAL8 *S2y, /**< [out] y-component of the dimensionless spin of object 2 */
617  REAL8 *S2z, /**< [out] z-component of the dimensionless spin of object 2 */
618  REAL8 *f_min, /**< [out] starting GW frequency (Hz) */
619  REAL8 *f_ref, /**< [out] reference frequency (Hz) */
620  REAL8 *distance, /**< [out] distance of source (m) */
621  INT4 *lmax, /**< [out] generate all modes with l <= lmax */
622  LALDict *params /**< Input lal dictionary with waveform (and optional) parameters **/
623 )
624 {
639 
640  return;
641 }
642 
643 /**
644  * Insert all the input arguments needed by XLALSimInspiralChooseFDWaveform() into a laldictionary.
645  */
647  REAL8 *m1, /**< [out] mass of companion 1 (kg) */
648  REAL8 *m2, /**< [out] mass of companion 2 (kg) */
649  REAL8 *S1x, /**< [out] x-component of the dimensionless spin of object 1 */
650  REAL8 *S1y, /**< [out] y-component of the dimensionless spin of object 1 */
651  REAL8 *S1z, /**< [out] z-component of the dimensionless spin of object 1 */
652  REAL8 *S2x, /**< [out] x-component of the dimensionless spin of object 2 */
653  REAL8 *S2y, /**< [out] y-component of the dimensionless spin of object 2 */
654  REAL8 *S2z, /**< [out] z-component of the dimensionless spin of object 2 */
655  REAL8 *distance, /**< [out] distance of source (m) */
656  REAL8 *inclination, /**< [out] inclination of source (rad) */
657  REAL8 *phiRef, /**< [out] reference orbital phase (rad) */
658  REAL8 *longAscNodes, /**< [out] longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
659  REAL8 *eccentricity, /**< [out] eccentrocity at reference epoch */
660  REAL8 *meanPerAno, /**< [out] mean anomaly of periastron */
661  REAL8 *deltaF, /**< [out] frequency interval (Hz) */
662  REAL8 *f_min, /**< [out] starting GW frequency (Hz) */
663  REAL8 *f_max, /**< [out] ending GW frequency (Hz) */
664  REAL8 *f_ref, /**< [out] reference frequency (Hz) */
665  LALDict *params /**< Input lal dictionary with waveform (and optional) parameters **/
666 )
667 {
668 
687 
688  return;
689 }
690 
691 /**
692  * Insert all the input arguments needed by XLALSimInspiralChooseFDModes() into a laldictionary.
693  */
695  REAL8 *m1, /**< [out] mass of companion 1 (kg) */
696  REAL8 *m2, /**< [out] mass of companion 2 (kg) */
697  REAL8 *S1x, /**< [out] x-component of the dimensionless spin of object 1 */
698  REAL8 *S1y, /**< [out] y-component of the dimensionless spin of object 1 */
699  REAL8 *S1z, /**< [out] z-component of the dimensionless spin of object 1 */
700  REAL8 *S2x, /**< [out] x-component of the dimensionless spin of object 2 */
701  REAL8 *S2y, /**< [out] y-component of the dimensionless spin of object 2 */
702  REAL8 *S2z, /**< [out] z-component of the dimensionless spin of object 2 */
703  REAL8 *deltaF, /**< [out] sampling interval (s) */
704  REAL8 *f_min, /**< [out] starting GW frequency (Hz) */
705  REAL8 *f_max, /**< [out] ending GW frequency (Hz) */
706  REAL8 *f_ref, /**< [out] reference GW frequency (Hz) */
707  REAL8 *phiRef, /**< [out] reference phase (rad) */
708  REAL8 *distance, /**< [out] distance of source (m) */
709  REAL8 *inclination, /**< [out] inclination of source (rad) */
710  LALDict *params /**< Input lal dictionary with waveform (and optional) parameters **/
711 )
712 {
728 
729  return;
730 }
731 
732 
733 
734 
735 
736  /** @} */
737 
738 /**
739  * @name General Waveform Switching Generation Routines
740  * @{
741  */
742 
743 /**
744  * Chooses between different approximants when requesting a waveform to be generated
745  * For spinning waveforms, all known spin effects up to given PN order are included
746  * Returns the waveform in the time domain.
747  *
748  * The parameters passed must be in SI units.
749  */
751  REAL8TimeSeries **hplus, /**< +-polarization waveform */
752  REAL8TimeSeries **hcross, /**< x-polarization waveform */
753  const REAL8 m1, /**< mass of companion 1 (kg) */
754  const REAL8 m2, /**< mass of companion 2 (kg) */
755  const REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
756  const REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
757  const REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
758  const REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
759  const REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
760  const REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
761  const REAL8 distance, /**< distance of source (m) */
762  const REAL8 inclination, /**< inclination of source (rad) */
763  const REAL8 phiRef, /**< reference orbital phase (rad) */
764  const REAL8 longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
765  const REAL8 eccentricity, /**< eccentrocity at reference epoch */
766  const REAL8 UNUSED meanPerAno, /**< mean anomaly of periastron */
767  const REAL8 deltaT, /**< sampling interval (s) */
768  const REAL8 f_min, /**< starting GW frequency (Hz) */
769  REAL8 f_ref, /**< reference GW frequency (Hz) */
770  LALDict *params, /**< LAL dictionary containing accessory parameters */
771  const Approximant approximant /**< post-Newtonian approximant to use for waveform production */
772  )
773 {
774  LALSimInspiralGenerator *generator;
775  int ret;
776 
778  XLAL_CHECK(generator, XLAL_EFUNC);
779 
780  if (params == NULL) {
782  }
783  else {
785  }
787 
805 
806  ret = XLALSimInspiralGenerateTDWaveform(hplus, hcross, params, generator);
809 
810  return ret;
811 }
812 
813 /**
814  * Chooses between different approximants when requesting a waveform to be generated
815  * For spinning waveforms, all known spin effects up to given PN order are included
816  * Returns the waveform in the frequency domain.
817  */
819  COMPLEX16FrequencySeries **hptilde, /**< FD plus polarization */
820  COMPLEX16FrequencySeries **hctilde, /**< FD cross polarization */
821  const REAL8 m1, /**< mass of companion 1 (kg) */
822  const REAL8 m2, /**< mass of companion 2 (kg) */
823  const REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
824  const REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
825  const REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
826  const REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
827  const REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
828  const REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
829  const REAL8 distance, /**< distance of source (m) */
830  const REAL8 inclination, /**< inclination of source (rad) */
831  const REAL8 phiRef, /**< reference orbital phase (rad) */
832  const REAL8 longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
833  const REAL8 eccentricity, /**< eccentricity at reference epoch */
834  const REAL8 UNUSED meanPerAno, /**< mean anomaly of periastron */
835  // frequency sampling parameters, no default value
836  const REAL8 deltaF, /**< sampling interval (Hz) */
837  const REAL8 f_min, /**< starting GW frequency (Hz) */
838  const REAL8 f_max, /**< ending GW frequency (Hz) */
839  REAL8 f_ref, /**< Reference frequency (Hz) */
840  LALDict *params, /**< LAL dictionary containing accessory parameters */
841  const Approximant approximant /**< post-Newtonian approximant to use for waveform production */
842  )
843 {
844  LALSimInspiralGenerator *generator;
845  int ret;
846 
848  XLAL_CHECK(generator, XLAL_EFUNC);
849 
850  if (params == NULL) {
852  }
853  else {
855  }
857 
858  /* Avoid duplication of arguments when called from XLALSimInspiralChoose(Generate)TDWaveform */
859  const char *remove_keys[12] = {"total_mass", "chirp_mass", "mass_difference", "reduced_mass", "mass_ratio", "sym_mass_ratio", \
860  "spin1_norm", "spin1_tilt", "spin1_phi", "spin2_norm", "spin2_tilt", "spin2_phi"};
861  for(size_t j = 0; j < sizeof(remove_keys)/sizeof(*remove_keys); ++j){
862  XLALDictRemove(params, remove_keys[j]);
863  }
864 
883 
884  ret = XLALSimInspiralGenerateFDWaveform(hptilde, hctilde, params, generator);
887 
888  return ret;
889 }
890 
891 /**
892  * @brief Generates an time domain inspiral waveform using the specified approximant; the
893  * resulting waveform is appropriately conditioned, suitable for injection into data,
894  * and decomposed into the (2, \f$\pm\f$ 2), spin -2 weighted spherical harmonic modes.
895  * NOTE: This is an algebraic decomposition, and will only be correct for approximants
896  * which use only the dominant 2, \f$\pm\f$ 2 mode.
897  *
898  * For spinning waveforms, all known spin effects up to given PN order are included
899  *
900  * This routine can generate FD approximants and transform them into the time domain.
901  * Waveforms are generated beginning at a slightly lower starting frequency and tapers
902  * are put in this early region so that the waveform smoothly turns on. Artifacts at
903  * the very end of the waveform are also tapered. The resulting waveform is high-pass
904  * filtered at frequency f_min so that it should have little content at lower frequencies.
905  *
906  * This routine used to have one additional parameter relative to XLALSimInspiralChooseTDWaveform:
907  * the redshift, z, of the waveform, which is now stuffed into the LALDict structure.
908  * This should be set to zero (default value) for sources in the nearby universe (that are nearly at rest relative to the
909  * earth). For sources at cosmological distances, the mass parameters m1 and m2 should
910  * be interpreted as the physical (source frame) masses of the bodies and the distance
911  * parameter r is the comoving (transverse) distance. If the calling routine has already
912  * applied cosmological "corrections" to m1 and m2 and regards r as a luminosity distance
913  * then the redshift factor should again be set to zero.
914  *
915  * @note The parameters passed must be in SI units.
916  */
918  REAL8 m1, /**< mass of companion 1 (kg) */
919  REAL8 m2, /**< mass of companion 2 (kg) */
920  REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
921  REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
922  REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
923  REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
924  REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
925  REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
926  REAL8 distance, /**< distance of source (m) */
927  REAL8 phiRef, /**< reference orbital phase (rad) */
928  REAL8 longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
929  REAL8 eccentricity, /**< eccentrocity at reference epoch */
930  REAL8 meanPerAno, /**< mean anomaly of periastron */
931  REAL8 deltaT, /**< sampling interval (s) */
932  REAL8 f_min, /**< starting GW frequency (Hz) */
933  REAL8 f_ref, /**< reference GW frequency (Hz) */
934  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
935  Approximant approximant /**< post-Newtonian approximant to use for waveform production */
936  )
937 {
938 
939  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) ) {
940  XLALPrintError("Non-zero transverse spins were given, but it is not possible to recover modes from H+ and Hx for precessing waveforms.\n");
942  }
943 
944  REAL8TimeSeries *hplus = NULL, *hcross = NULL;
945  COMPLEX16TimeSeries *h22,*h2m2;
946  SphHarmTimeSeries *hlm;
947  UINT4 j;
948  int retval;
949  float fac = XLALSpinWeightedSphericalHarmonic(0., 0., -2, 2,2);
950 
951  /* Generate waveform via on-axis emission. Assumes only (2,2) and (2,-2) emission */
952  retval = XLALSimInspiralTD(&hplus, &hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, distance, 0., phiRef, longAscNodes, eccentricity, meanPerAno, deltaT, f_min, f_ref, LALparams, approximant);
953  if (retval < 0)
955 
956  /* Step 1: Create COMPLEX16 TimeSeries and populate them */
957  h22 = XLALCreateCOMPLEX16TimeSeries("h22", &(hplus)->epoch, 0, deltaT, &lalStrainUnit, (hplus)->data->length);
958  h2m2 = XLALCreateCOMPLEX16TimeSeries("h2m2", &(hplus)->epoch, 0, deltaT, &lalStrainUnit, (hplus)->data->length);
959  for (j=0; j< (hplus)->data->length; j++) {
960  h22->data->data[j] = ((hplus)->data->data[j] - I*((hcross)->data->data[j]))/fac;
961  h2m2->data->data[j] = ((hplus)->data->data[j] + I*((hcross)->data->data[j]))/fac;
962  }
963 
964  /* Step 2: Add them into the data */
965  hlm = XLALSphHarmTimeSeriesAddMode(NULL, h22, 2, 2);
966  hlm = XLALSphHarmTimeSeriesAddMode(hlm, h2m2, 2, -2);
967 
968  /* Step 3: Clean up */
973 
974  return hlm;
975 }
976 
977 /** Helper routines for XLALSimInspiralTD(): performs conditioning of a TD waveform */
979  REAL8TimeSeries **hplus, /**< +-polarization waveform */
980  REAL8TimeSeries **hcross, /**< x-polarization waveform */
981  REAL8 m1, /**< mass of companion 1 (kg) */
982  REAL8 m2, /**< mass of companion 2 (kg) */
983  REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
984  REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
985  REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
986  REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
987  REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
988  REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
989  REAL8 distance, /**< distance of source (m) */
990  REAL8 inclination, /**< inclination of source (rad) */
991  REAL8 phiRef, /**< reference orbital phase (rad) */
992  REAL8 longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
993  REAL8 eccentricity, /**< eccentrocity at reference epoch */
994  REAL8 meanPerAno, /**< mean anomaly of periastron */
995  REAL8 deltaT, /**< sampling interval (s) */
996  REAL8 f_min, /**< starting GW frequency (Hz) */
997  REAL8 f_ref, /**< reference GW frequency (Hz) */
998  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
999  Approximant approximant /**< post-Newtonian approximant to use for waveform production */
1000 )
1001 {
1002  const double extra_time_fraction = 0.1; /* fraction of waveform duration to add as extra time for tapering */
1003  const double extra_cycles = 3.0; /* more extra time measured in cycles at the starting frequency */
1004  double original_f_min = f_min; /* f_min might be overwritten below, so keep original value */
1005  double tchirp, tmerge, textra;
1006  double fisco, fstart;
1007  double s;
1008  int retval;
1009 
1011  XLAL_ERROR(XLAL_EINVAL, "Invalid approximant: not a TD approximant");
1012 
1013  /* adjust the reference frequency for certain precessing approximants:
1014  * if that approximate interprets f_ref==0 to be f_min, set f_ref=f_min;
1015  * otherwise do nothing */
1017 
1018  /* apply redshift correction to dimensionful source-frame quantities */
1020  if (z != 0.0) {
1021  m1 *= (1.0 + z);
1022  m2 *= (1.0 + z);
1023  distance *= (1.0 + z); /* change from comoving (transverse) distance to luminosity distance */
1024  }
1025  /* set redshift to zero so we don't accidentally apply it again later */
1026  z=0.;
1027  if (LALparams)
1029 
1030  /* if the requested low frequency is below the lowest Kerr ISCO
1031  * frequency then change it to that frequency */
1032  fisco = 1.0 / (pow(9.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
1033  if (f_min > fisco)
1034  f_min = fisco;
1035 
1036  /* upper bound on the chirp time starting at f_min */
1037  tchirp = XLALSimInspiralChirpTimeBound(f_min, m1, m2, S1z, S2z);
1038 
1039  /* upper bound on the final black hole spin */
1041 
1042  /* upper bound on the final plunge, merger, and ringdown time */
1044 
1045  /* extra time to include for all waveforms to take care of situations
1046  * where the frequency is close to merger (and is sweeping rapidly):
1047  * this is a few cycles at the low frequency */
1048  textra = extra_cycles / f_min;
1049 
1050  /* time domain approximant: condition by generating a waveform
1051  * with a lower starting frequency and apply tapers in the
1052  * region between that lower frequency and the requested
1053  * frequency f_min; here compute a new lower frequency */
1054  fstart = XLALSimInspiralChirpStartFrequencyBound((1.0 + extra_time_fraction) * tchirp + tmerge + textra, m1, m2);
1055 
1056  /* generate the waveform in the time domain starting at fstart */
1057  retval = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, distance, inclination, phiRef, longAscNodes, eccentricity, meanPerAno, deltaT, fstart, f_ref, LALparams, approximant);
1058  if (retval < 0)
1060 
1061  /* condition the time domain waveform by tapering in the extra time
1062  * at the beginning and high-pass filtering above original f_min */
1063  XLALSimInspiralTDConditionStage1(*hplus, *hcross, extra_time_fraction * tchirp + textra, original_f_min);
1064 
1065  /* final tapering at the beginning and at the end to remove filter transients */
1066 
1067  /* waveform should terminate at a frequency >= Schwarzschild ISCO
1068  * so taper one cycle at this frequency at the end; should not make
1069  * any difference to IMR waveforms */
1070  fisco = 1.0 / (pow(6.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
1071  XLALSimInspiralTDConditionStage2(*hplus, *hcross, f_min, fisco);
1072 
1073  return 0;
1074 }
1075 
1076 /** Helper routines for XLALSimInspiralTD(): performs conditioning of a FD waveform and transforms it to TD */
1078  REAL8TimeSeries **hplus, /**< +-polarization waveform */
1079  REAL8TimeSeries **hcross, /**< x-polarization waveform */
1080  REAL8 m1, /**< mass of companion 1 (kg) */
1081  REAL8 m2, /**< mass of companion 2 (kg) */
1082  REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
1083  REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
1084  REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
1085  REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
1086  REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
1087  REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
1088  REAL8 distance, /**< distance of source (m) */
1089  REAL8 inclination, /**< inclination of source (rad) */
1090  REAL8 phiRef, /**< reference orbital phase (rad) */
1091  REAL8 longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
1092  REAL8 eccentricity, /**< eccentrocity at reference epoch */
1093  REAL8 meanPerAno, /**< mean anomaly of periastron */
1094  REAL8 deltaT, /**< sampling interval (s) */
1095  REAL8 f_min, /**< starting GW frequency (Hz) */
1096  REAL8 f_ref, /**< reference GW frequency (Hz) */
1097  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
1098  Approximant approximant /**< post-Newtonian approximant to use for waveform production */
1099 )
1100 {
1101  COMPLEX16FrequencySeries *hptilde = NULL;
1102  COMPLEX16FrequencySeries *hctilde = NULL;
1103  REAL8FFTPlan *plan;
1104  size_t chirplen, end, k;
1105  double tshift;
1106  const double extra_time_fraction = 0.1; /* fraction of waveform duration to add as extra time for tapering */
1107  const double extra_cycles = 3.0; /* more extra time measured in cycles at the starting frequency */
1108  double original_f_min = f_min; /* f_min might be overwritten below, so keep original value */
1109  double f_max = 0.5 / deltaT;
1110  double tchirp, tmerge, textra;
1111  double fisco, fstart;
1112  double s;
1113  int retval;
1114 
1116  XLAL_ERROR(XLAL_EINVAL, "Invalid approximant: not a FD approximant");
1117 
1118  /* adjust the reference frequency for certain precessing approximants:
1119  * if that approximate interprets f_ref==0 to be f_min, set f_ref=f_min;
1120  * otherwise do nothing */
1122 
1123  /* apply redshift correction to dimensionful source-frame quantities */
1125  if (z != 0.0) {
1126  m1 *= (1.0 + z);
1127  m2 *= (1.0 + z);
1128  distance *= (1.0 + z); /* change from comoving (transverse) distance to luminosity distance */
1129  }
1130  /* set redshift to zero so we don't accidentally apply it again later */
1131  z=0.;
1132  if (LALparams)
1134 
1135  /* if the requested low frequency is below the lowest Kerr ISCO
1136  * frequency then change it to that frequency */
1137  fisco = 1.0 / (pow(9.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
1138  if (f_min > fisco)
1139  f_min = fisco;
1140 
1141  /* upper bound on the chirp time starting at f_min */
1142  tchirp = XLALSimInspiralChirpTimeBound(f_min, m1, m2, S1z, S2z);
1143 
1144  /* upper bound on the final black hole spin */
1146 
1147  /* upper bound on the final plunge, merger, and ringdown time */
1149 
1150  /* extra time to include for all waveforms to take care of situations
1151  * where the frequency is close to merger (and is sweeping rapidly):
1152  * this is a few cycles at the low frequency */
1153  textra = extra_cycles / f_min;
1154 
1155  /* generate the conditioned waveform in the frequency domain */
1156  /* note: redshift factor has already been applied above */
1157  /* set deltaF = 0 to get a small enough resolution */
1158  retval = XLALSimInspiralFD(&hptilde, &hctilde, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, distance, inclination, phiRef, longAscNodes, eccentricity, meanPerAno, 0.0, f_min, f_max, f_ref, LALparams, approximant);
1159  if (retval < 0)
1161 
1162  /* we want to make sure that this waveform will give something
1163  * sensible if it is later transformed into the time domain:
1164  * to avoid the end of the waveform wrapping around to the beginning,
1165  * we shift waveform backwards in time and compensate for this
1166  * shift by adjusting the epoch -- note that XLALSimInspiralFD
1167  * guarantees that there is extra padding to do this */
1168  tshift = round(textra / deltaT) * deltaT; /* integer number of samples */
1169  for (k = 0; k < hptilde->data->length; ++k) {
1170  double complex phasefac = cexp(2.0 * M_PI * I * k * hptilde->deltaF * tshift);
1171  hptilde->data->data[k] *= phasefac;
1172  hctilde->data->data[k] *= phasefac;
1173  }
1174  XLALGPSAdd(&hptilde->epoch, tshift);
1175  XLALGPSAdd(&hctilde->epoch, tshift);
1176 
1177  /* transform the waveform into the time domain */
1178  chirplen = 2 * (hptilde->data->length - 1);
1179  *hplus = XLALCreateREAL8TimeSeries("H_PLUS", &hptilde->epoch, 0.0, deltaT, &lalStrainUnit, chirplen);
1180  *hcross = XLALCreateREAL8TimeSeries("H_CROSS", &hctilde->epoch, 0.0, deltaT, &lalStrainUnit, chirplen);
1181  plan = XLALCreateReverseREAL8FFTPlan(chirplen, 0);
1182  if (!(*hplus) || !(*hcross) || !plan) {
1185  XLALDestroyREAL8TimeSeries(*hcross);
1189  }
1190  XLALREAL8FreqTimeFFT(*hplus, hptilde, plan);
1191  XLALREAL8FreqTimeFFT(*hcross, hctilde, plan);
1192 
1193  /* apply time domain filter at original f_min */
1194  XLALHighPassREAL8TimeSeries(*hplus, original_f_min, 0.99, 8);
1195  XLALHighPassREAL8TimeSeries(*hcross, original_f_min, 0.99, 8);
1196 
1197  /* compute how long a chirp we should have */
1198  /* revised estimate of chirp length from new start frequency */
1199  fstart = XLALSimInspiralChirpStartFrequencyBound((1.0 + extra_time_fraction) * tchirp, m1, m2);
1200  tchirp = XLALSimInspiralChirpTimeBound(fstart, m1, m2, S1z, S2z);
1201 
1202  /* total expected chirp length includes merger */
1203  chirplen = round((tchirp + tmerge) / deltaT);
1204 
1205  /* amount to snip off at the end is tshift */
1206  end = (*hplus)->data->length - round(tshift / deltaT);
1207 
1208  /* snip off extra time at beginning and at the end */
1209  XLALResizeREAL8TimeSeries(*hplus, end - chirplen, chirplen);
1210  XLALResizeREAL8TimeSeries(*hcross, end - chirplen, chirplen);
1211 
1212  /* clean up */
1216 
1217  /* final tapering at the beginning and at the end to remove filter transients */
1218 
1219  /* waveform should terminate at a frequency >= Schwarzschild ISCO
1220  * so taper one cycle at this frequency at the end; should not make
1221  * any difference to IMR waveforms */
1222  fisco = 1.0 / (pow(6.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
1223  XLALSimInspiralTDConditionStage2(*hplus, *hcross, f_min, fisco);
1224 
1225  return 0;
1226 }
1227 
1228 /**
1229  * @brief Generates an time domain inspiral waveform using the specified approximant; the
1230  * resulting waveform is appropriately conditioned and suitable for injection into data.
1231  *
1232  * For spinning waveforms, all known spin effects up to given PN order are included
1233  *
1234  * This routine can generate FD approximants and transform them into the time domain.
1235  * Waveforms are generated beginning at a slightly lower starting frequency and tapers
1236  * are put in this early region so that the waveform smoothly turns on. Artifacts at
1237  * the very end of the waveform are also tapered. The resulting waveform is high-pass
1238  * filtered at frequency f_min so that it should have little content at lower frequencies.
1239 
1240  * If calling with precessing time-domain approximants for which the reference frequency
1241  * is the starting frequency, or if calling with NR_hdf5 approximant, the starting
1242  * frequency is not altered. Uses XLALSimInspiralGetSpinFreqFromApproximant to determine
1243  * appropriate behaviour.
1244  * Similarly, if calling time-domain models for which a starting frequency of
1245  * zero is allowed (as set in
1246  * XLALSimInspiralGetAllowZeroMinFreqFromApproximant), the starting frequency
1247  * is never altered, independent of f_min.
1248  *
1249  * This routine used to have one additional parameter relative to XLALSimInspiralChooseTDWaveform:
1250  * the redshift, z, of the waveform, which is now stuffed into the LALDict structure.
1251  * This should be set to zero (default value) for sources in the nearby universe (that are nearly at rest relative to the
1252  * earth). For sources at cosmological distances, the mass parameters m1 and m2 should
1253  * be interpreted as the physical (source frame) masses of the bodies and the distance
1254  * parameter r is the comoving (transverse) distance. If the calling routine has already
1255  * applied cosmological "corrections" to m1 and m2 and regards r as a luminosity distance
1256  * then the redshift factor should again be set to zero.
1257  *
1258  * @note The parameters passed must be in SI units.
1259  */
1261  REAL8TimeSeries **hplus, /**< +-polarization waveform */
1262  REAL8TimeSeries **hcross, /**< x-polarization waveform */
1263  REAL8 m1, /**< mass of companion 1 (kg) */
1264  REAL8 m2, /**< mass of companion 2 (kg) */
1265  REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
1266  REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
1267  REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
1268  REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
1269  REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
1270  REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
1271  REAL8 distance, /**< distance of source (m) */
1272  REAL8 inclination, /**< inclination of source (rad) */
1273  REAL8 phiRef, /**< reference orbital phase (rad) */
1274  REAL8 longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
1275  REAL8 eccentricity, /**< eccentrocity at reference epoch */
1276  REAL8 meanPerAno, /**< mean anomaly of periastron */
1277  REAL8 deltaT, /**< sampling interval (s) */
1278  REAL8 f_min, /**< starting GW frequency (Hz) */
1279  REAL8 f_ref, /**< reference GW frequency (Hz) */
1280  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
1281  Approximant approximant /**< post-Newtonian approximant to use for waveform production */
1282  )
1283 {
1284  int ret;
1285 
1286  /* set condition flag */
1287  if (LALparams == NULL) {
1288  LALparams = XLALCreateDict();
1289  } else {
1290  LALparams = XLALDictDuplicate(LALparams);
1291  if (XLALDictContains(LALparams, "condition"))
1292  XLALDictRemove(LALparams, "condition");
1293  }
1294  XLALDictInsertINT4Value(LALparams, "condition", 2);
1295 
1296  ret = XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, distance, inclination, phiRef, longAscNodes, eccentricity, meanPerAno, deltaT, f_min, f_ref, LALparams, approximant);
1297  XLALDestroyDict(LALparams);
1298 
1299  return ret;
1300 }
1301 
1302 /**
1303  * @brief Generates a frequency domain inspiral waveform using the specified approximant; the
1304  * resulting waveform is appropriately conditioned and suitable for injection into data.
1305  *
1306  * For spinning waveforms, all known spin effects up to given PN order are included.
1307  *
1308  * This routine can generate TD approximants and transform them into the frequency domain.
1309  * Waveforms are generated beginning at a slightly lower starting frequency and tapers
1310  * are put in this early region so that the waveform smoothly turns on.
1311  *
1312  * If an FD approximant is used, this routine applies tapers in the frequency domain
1313  * between the slightly-lower frequency and the requested f_min. Also, the phase of the
1314  * waveform is adjusted to introduce a time shift. This time shift should allow the
1315  * resulting waveform to be Fourier transformed into the time domain without wrapping
1316  * the end of the waveform to the beginning.
1317  *
1318  * This routine assumes that f_max is the Nyquist frequency of a corresponding time-domain
1319  * waveform, so that deltaT = 0.5 / f_max. If deltaF is set to 0 then this routine computes
1320  * a deltaF that is small enough to represent the Fourier transform of a time-domain waveform
1321  * while ensuring the length of the time-domain signal if a power of 2.
1322  * If deltaF is specified but f_max / deltaF is not a power of 2, and the waveform approximant
1323  * is a time-domain approximant, then f_max is increased so that f_max / deltaF is the next
1324  * power of 2. (If the user wishes to discard the extra high frequency content, this must
1325  * be done separately.)
1326  *
1327  * The user should take care to ensure that deltaF is sufficiently small to contain the full
1328  * signal (time series duration = 1 / deltaF). If the provided deltaF is too large the signal
1329  * will be abruptly truncated for time-domain waveform generators. For frequency-domain
1330  * generators the signal will be aliased in the frequency domain.
1331  *
1332  * Similarly, if the provided f_max is less than the ringdown frequency the underlying waveform
1333  * generator may raise an error. If not, the frequency domain signal will be aliased in the
1334  * frequency domain.
1335  *
1336  * Some waveform approximants have built in checks for the maximum frequency and signal length
1337  *
1338  * This routine used to have one additional parameter relative to XLALSimInspiralChooseTDWaveform:
1339  * the redshift, z, of the waveform, which is now stuffed into the LALDict.
1340  * This should be set to zero (default value) for sources in the nearby universe (that are nearly at rest relative to the
1341  * earth). For sources at cosmological distances, the mass parameters m1 and m2 should
1342  * be interpreted as the physical (source frame) masses of the bodies and the distance
1343  * parameter r is the comoving (transverse) distance. If the calling routine has already
1344  * applied cosmological "corrections" to m1 and m2 and regards r as a luminosity distance
1345  * then the redshift factor should again be set to zero.
1346  *
1347  *
1348  * @note The parameters passed must be in SI units.
1349  */
1351  COMPLEX16FrequencySeries **hptilde, /**< FD plus polarization */
1352  COMPLEX16FrequencySeries **hctilde, /**< FD cross polarization */
1353  REAL8 m1, /**< mass of companion 1 (kg) */
1354  REAL8 m2, /**< mass of companion 2 (kg) */
1355  REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
1356  REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
1357  REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
1358  REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
1359  REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
1360  REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
1361  REAL8 distance, /**< distance of source (m) */
1362  REAL8 inclination, /**< inclination of source (rad) */
1363  REAL8 phiRef, /**< reference orbital phase (rad) */
1364  REAL8 longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
1365  REAL8 eccentricity, /**< eccentricity at reference epoch */
1366  REAL8 meanPerAno, /**< mean anomaly of periastron */
1367  REAL8 deltaF, /**< sampling interval (Hz) */
1368  REAL8 f_min, /**< starting GW frequency (Hz) */
1369  REAL8 f_max, /**< ending GW frequency (Hz) */
1370  REAL8 f_ref, /**< Reference frequency (Hz) */
1371  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
1372  Approximant approximant /**< post-Newtonian approximant to use for waveform production */
1373  )
1374 {
1375  int ret;
1376 
1377  /* set condition flag */
1378  if (LALparams == NULL) {
1379  LALparams = XLALCreateDict();
1380  } else {
1381  LALparams = XLALDictDuplicate(LALparams);
1382  if (XLALDictContains(LALparams, "condition"))
1383  XLALDictRemove(LALparams, "condition");
1384  }
1385  XLALDictInsertINT4Value(LALparams, "condition", 2);
1386 
1387  ret = XLALSimInspiralChooseFDWaveform(hptilde, hctilde, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, distance, inclination, phiRef, longAscNodes, eccentricity, meanPerAno, deltaF, f_min, f_max, f_ref, LALparams, approximant);
1388  XLALDestroyDict(LALparams);
1389 
1390  return ret;
1391 }
1392 
1393 /**
1394  * @deprecated Use XLALSimInspiralChooseTDWaveform() instead
1395  *
1396  * Chooses between different approximants when requesting a waveform to be generated
1397  * For spinning waveforms, all known spin effects up to given PN order are included
1398  *
1399  * The parameters passed must be in SI units.
1400  */
1402  REAL8TimeSeries **hplus, /**< +-polarization waveform */
1403  REAL8TimeSeries **hcross, /**< x-polarization waveform */
1404  const REAL8 m1, /**< mass of companion 1 (kg) */
1405  const REAL8 m2, /**< mass of companion 2 (kg) */
1406  const REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
1407  const REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
1408  const REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
1409  const REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
1410  const REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
1411  const REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
1412  const REAL8 distance, /**< distance of source (m) */
1413  const REAL8 inclination, /**< inclination of source (rad) */
1414  const REAL8 phiRef, /**< reference orbital phase (rad) */
1415  const REAL8 longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
1416  const REAL8 eccentricity, /**< eccentrocity at reference epoch */
1417  const REAL8 meanPerAno, /**< mean anomaly of periastron */
1418  // frequency sampling parameters, no default value
1419  const REAL8 deltaT, /**< sampling interval (s) */
1420  const REAL8 f_min, /**< starting GW frequency (Hz) */
1421  const REAL8 f_ref, /**< reference GW frequency (Hz) */
1422  LALDict *LALpars, /**< LAL dictionary containing accessory parameters */
1423  const Approximant approximant /**< post-Newtonian approximant to use for waveform production */)
1424 {
1425  XLAL_PRINT_DEPRECATION_WARNING("XLALSimInspiralChooseTDWaveform");
1426 
1427  return XLALSimInspiralChooseTDWaveform(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z,
1428  distance, inclination, phiRef, longAscNodes,
1429  eccentricity, meanPerAno, deltaT, f_min, f_ref,
1430  LALpars, approximant);
1431 }
1432 
1433 /** @} */
1434 
1435 /**
1436  * @name General Waveform Switching Mode Generation Routines
1437  * @{
1438  */
1439 
1440 /**
1441  * Interface to compute a set of -2 spin-weighted spherical harmonic modes
1442  * for a binary inspiral for a given waveform approximant.
1443  * PN Approximants (TaylorT1 - T4), EOBNRv2 (EOBNRv2HM), NRSur7dq2, NRSur7dq4
1444  * NRHybSur3dq8 and spin-precessing SpintaylorT1, T5, T4 are implemented.
1445  *
1446  * The EOBNRv2 model returns the (2,2), (2,1), (3,3), (4,4), and (5,5) modes.
1447  * Note that the inclination parameter is not passed to create hlm modes,
1448  * hence to recover the correct h+,x one has to combine the hlm modes with
1449  * Euler angles alpha=0, iota=inclination, psi=0,Pi/2 (according to the approximat) i.e.
1450  * (h+ + I hx) (psi,iota,alpha)= e^(-2Ialpha) Sum_{l,m} Y_lm(-iota,-psi) h_lm,
1451  * or equivalently rotate h_lm -> h'_lm=DWigner(psi,iota,alpha) h_lm
1452  * and then obtain
1453  * (h+ + I hx) = Sum_{l,m} Y_lm(0,0) h'_lm,
1454  */
1456  UNUSED REAL8 phiRef, /**< reference orbital phase (rad). This variable is not used and only kept here for backwards compatibility */
1457  REAL8 deltaT, /**< sampling interval (s) */
1458  REAL8 m1, /**< mass of companion 1 (kg) */
1459  REAL8 m2, /**< mass of companion 2 (kg) */
1460  REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
1461  REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
1462  REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
1463  REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
1464  REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
1465  REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
1466  REAL8 f_min, /**< starting GW frequency (Hz) */
1467  REAL8 f_ref, /**< reference GW frequency (Hz) */
1468  REAL8 distance, /**< distance of source (m) */
1469  LALDict *params, /**< LAL dictionary containing accessory parameters */
1470  int lmax, /**< generate all modes with l <= lmax */
1471  Approximant approximant /**< post-Newtonian approximant to use for waveform production */
1472  )
1473 {
1474  LALSimInspiralGenerator *generator;
1475  SphHarmTimeSeries *hlms = NULL;
1476 
1478  if (!(generator))
1480 
1481  if (params == NULL) {
1482  params = XLALCreateDict();
1483  }
1484  else {
1486  }
1487  if (!(params))
1489 
1504 
1505  XLALSimInspiralGenerateTDModes(&hlms, params, generator);
1508 
1509  return hlms;
1510 }
1511 
1512 /**
1513  * @brief Interface to compute a set of -2 spin-weighted spherical harmonic modes
1514  * for a binary merger for a given waveform approximant in the Fourier domain.
1515  * Non-precessing models IMRPhenomXHM, SEOBNRv4HM_ROM, SEOBNRv5(HM)_ROM and IMRPhenomHM and the
1516  * precessing IMRPhenomXPHM are implemented.
1517  * By default, all the modes available in the model are returned, although the list
1518  * can be specified through the ModeArray option in the LAL dictionary.
1519  * @details
1520  * In the Fourier domain the modes span over the whole frequency regime (positive and negative frequencies).
1521  * However, in the aligned spin case, the modes have support only in one half of the frequency regime.
1522  * The LAL conventions establish that the negative modes (m<0) have support for positive frequencies while
1523  * the positive modes (m>0) have support for negative frequencies (this is based in the right hand rule and
1524  * Fourier transform definition in LAL).
1525  * Due to the equatorial symmetry of non-precessng systems, there exist a relation between them: h_{lm}(f) = (-1)^l h*_{l-m}(-f).
1526  * In the precessing case this symmetry is broken and all the modes have support for both positive and negative frequencies.
1527  *
1528  * For this reason, the ouput SphHarmFrequencySeries object will return the modes in the whole frequency range.
1529  * The frequencies of this object will be sorted as: -f_max,...,-f_min,...0,...,f_min,...,f_max.
1530  * The values of the waveform will be sorted correspondingly. Consequently, in the aligned spin case, half of the frequency spectrum consists of zeros.
1531  *
1532  * It is relevant to mention why the arguments inclination and phiRef are needed for computing the h_lm.
1533  * For AS models the argument inclination is irrelevant and will not be use since it only enters in the Ylm. However, for the precessing model,
1534  * since the modes are returned in the J-frame, we need the inclination argument to carry out the Euler transformation from the co-precessing L-frame
1535  * to the inertial J-frame. Regarding the argument phiRef, this affects the output of the precessing model due to the same reason as before, while for the AS models
1536  * it would not affect the output of SEOBNRv4HM_ROM, SEOBNRv5(HM)_ROM but will change the output of IMRPhenomHM and IMRPhenomXHM (this is due to the internals workings of the models).
1537  * If one wants to built the polarizations from the individual modes of ChooseFDModes must be aware of this behaviour.
1538  * Ideally, one would call ChooseFDModes with phiRef=0 to obtain the h_lms, then build the Fourier domain polarizations as
1539  *
1540  * h_+ (f) = 1/2 sum_{l=2} sum_{m=-l}^{m=l} ( h_lm(f) * Y_lm(theta, vphi) + h*_lm(-f) * Y*_lm(theta, vphi) )
1541  * h_x (f) = i/2 sum_{l=2} sum_{m=-l}^{m=l} ( h_lm(f) * Y_lm(theta, vphi) - h*_lm(-f) * Y*_lm(theta, vphi) )
1542  *
1543  * where theta is the inclination and vphi is pi/2 - phiRef.
1544  *
1545  * If one does this, one will find generally a very close result to ChooseFDWaveform with very small mismatches (~10^-9 for IMRPhenomXHM),
1546  * and this is what is found if one uses the XLALSimInspiralPolarizationsFromSphHarmFrequencySeries function, however this is not close to machine precision.
1547  * The reason is that IMRPhenomHM and IMRPhenomXHM use internally the phiRef argument to compute the h_lms because at that time phiRef was considered to be also a reference
1548  * phase for the h_lms and not just the argument for the azimuthal angle in the Y_lms.
1549  * To take this into account we provide also the function XLALSimInspiralPolarizationsFromChooseFDModes which build the polarizations in the proper way for each
1550  * model returning a result close to machine precision with ChooseFDWaveform.
1551  *
1552  * For the precessing model IMRPhenomXPHM, since the h_lms are returned in the J-frame one must build the polarizations using theta = theta_JN and vphi = 0.
1553  * The parameter theta_JN is computed internally when using XLALSimInspiralPolarizationsFromChooseFDModes and again here the result is close to machine precision to ChooseFDWaveform.
1554  * However, one would have to compute theta_JN personally when using XLALSimInspiralPolarizationsFromSphHarmFrequencySeries.
1555  * For IMRPhenomXPHM this parameter can be computed using XLALSimIMRPhenomXPCalculateModelParametersFromSourceFrame. Eventhough one would still have to correct with the polarization angle.
1556  *
1557  * By default all the modes available in the model will be returned, both positive and negative modes.
1558  * The mode content of AS models can be adjusted through the ModeArray option in the LAL dictionary argument, and it accepts any set of modes e.g. (2,2),(2,-1),(3,3),...
1559  * For IMRPhenomXPHM, we can specify both the modes in the co-precessing L-frame, which are used to do the twisting-up, and
1560  * the ouput modes in the inertial J-frame. The set of modes in the L-frame are specified with the standard ModeArray option
1561  * while the set of modes in the J-frame are specified in a new option called ModeArrayJframe. Notice that in IMRPhenomXPHM, ModeArray does not distinguish
1562  * between positive or negative modes and it always twists-up both positive and negative modes, i.e. the sets {(2,2)}, {(2,-2)} or {(2,2),(2,-2)} would return the same result.
1563  * For the modes in ModeArrayJframe, we can specify both positive or negative modes for example {(2,2),(2,-2),(2,-1),(3,3),...}.
1564  */
1566  REAL8 m1, /**< mass of companion 1 (kg) */
1567  REAL8 m2, /**< mass of companion 2 (kg) */
1568  REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
1569  REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
1570  REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
1571  REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
1572  REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
1573  REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
1574  REAL8 deltaF, /**< sampling interval (s) */
1575  REAL8 f_min, /**< starting GW frequency (Hz) */
1576  REAL8 f_max, /**< ending GW frequency (Hz) */
1577  REAL8 f_ref, /**< reference GW frequency (Hz) */
1578  REAL8 phiRef, /**< reference phase (rad) */
1579  REAL8 distance, /**< distance of source (m) */
1580  REAL8 inclination, /**< inclination of source (rad) */
1581  LALDict *params, /**< LAL dictionary containing accessory parameters (optional mode array) */
1582  Approximant approximant /**< approximant to use for waveform production */
1583  )
1584 {
1585 
1586  LALSimInspiralGenerator *generator;
1587  SphHarmFrequencySeries *hlms = NULL;
1588 
1590  if (!(generator))
1592 
1593  if (params == NULL) {
1594  params = XLALCreateDict();
1595  }
1596  else {
1598  }
1599  if (!(params))
1601 
1617 
1618 
1619  XLALSimInspiralGenerateFDModes(&hlms, params, generator);
1622 
1623  return hlms;
1624 }
1625 
1626 /**
1627  * @brief Interface to compute a conditioned set of -2 spin-weighted spherical
1628  * harmonic modes for a binary inspiral
1629  * @details
1630  * This routine is a wrapper for XLALSimInspiralChooseTDModes which applies
1631  * waveform conditioning to the modes generated by that routine. The conditioning
1632  * algorithm is analogous to that performed in XLALSimInspiralTD. Note that
1633  * the modes are high-pass filtered at frequency f_min, which is specified for
1634  * the m=2 mode, which means that the low-frequency part of the m=1 mode is
1635  * removed by the filtering. The phasing is computed with any of the TaylorT1,
1636  * T2, T3, T4 methods. It can also return the (2,2), (2,1), (3,3), (4,4),
1637  * (5,5) modes of the EOBNRv2 model. Note that EOBNRv2 will ignore ampO,
1638  * phaseO, lmax and f_ref arguments.
1639  * @param deltaT Sampling interval (s)
1640  * @param m1 Mass of companion 1 (kg)
1641  * @param m2 Mass of companion 2 (kg)
1642  * @param f_min Starting GW frequency (Hz)
1643  * @param f_ref Reference GW frequency (Hz)
1644  * @param r Distance of source (m)
1645  * @param LALpars LAL dictionary containing accesory parameters
1646  * @param lmax Generate all modes with l <= lmax
1647  * @param approximant Post-Newtonian approximant to use for waveform production
1648  * @return Linked list of SphHarmTimeSeries modes.
1649  */
1651 {
1652  const size_t min_taper_samples = 4;
1653  const double extra_time_fraction = 0.1; /* fraction of waveform duration to add as extra time for tapering */
1654  const double extra_cycles = 3.0; /* more extra time measured in cycles at the starting frequency */
1655  double original_f_min = f_min; /* f_min might be overwritten below, so keep original value */
1656  //double tchirp, tmerge, textra;
1657  //double fisco, fstart;
1658  double tchirp, textra;
1659  double fisco;
1660  //double s;
1661  size_t length, nzeros, ntaper;
1662  size_t j;
1663  SphHarmTimeSeries *modes, *hlm;
1664 
1665  /* if the requested low frequency is below the lowest Kerr ISCO frequency
1666  * then change it to that frequency */
1667  fisco = 1.0 / (pow(9.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
1668  if (f_min > fisco)
1669  f_min = fisco;
1670 
1671  /* upper bound on the chirp time starting at f_min */
1672  tchirp = XLALSimInspiralChirpTimeBound(f_min, m1, m2, 0.0, 0.0);
1673 
1674  /* upper bound on the final black hole spin */
1675  //s = XLALSimInspiralFinalBlackHoleSpinBound(0.0, 0.0);
1676 
1677  /* upper bound on the final plunge, merger, and ringdown time */
1678  //tmerge = XLALSimInspiralMergeTimeBound(m1, m2) + XLALSimInspiralRingdownTimeBound(m1 + m2, s);
1679 
1680  /* extra time to include for all waveforms to take care of situations
1681  * where the frequency is close to merger (and is sweeping rapidly):
1682  * this is a few cycles at the low frequency */
1683  textra = extra_cycles / f_min;
1684 
1685  /* condition by generating a waveform with a lower starting frequency and
1686  * apply tapers in the region between that lower frequency and the
1687  * requested frequency f_min; here compute a new lower frequency */
1688  // fstart = XLALSimInspiralChirpStartFrequencyBound((1.0 + extra_time_fraction) * tchirp + tmerge + textra, m1, m2);
1689 
1690  XLALPrintWarning("XLAL Warning - XLALSimInspiralModesTD does not yet implement spins - passing zeros\n");
1691  modes = XLALSimInspiralChooseTDModes(0.,deltaT, m1, m2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, f_min, f_ref, r, LALpars, lmax, approximant);
1692  if (!modes)
1694 
1695  /* Note: fstart and f_min are frequencies for a m=2 mode, while the
1696  * frequencies of the mth mode are f_m = m * f / 2; this means that if we
1697  * generate a waveform that starts at fstart in the m=2 mode then the m=1
1698  * mode starts at fstart/2 while the m=3 mode starts at 3*fstart/2, and so
1699  * on. However, the time it takes the m=2 mode to go from fstart to f_min
1700  * is the same as the time that a m=1 mode to go from fstart/2 to f_min/2,
1701  * etc., so we apply tapers over this time. The upshot is that the
1702  * resulting modes will be valid for frequencies above m * f_min / 2.
1703  * evolve from fstart to f_min is the same as the time to evolve from
1704  * 2*f_start/m to 2*f_min/m for the mth mode, so taper all modes over
1705  * taper this duration. */
1706  length = nzeros = modes->mode->data->length;
1707  for (hlm = modes; hlm; hlm = hlm->next) {
1708  /* some waveform generators zero-pad the end of the waveform, and we
1709  * want to remove this; however, we want all modes to have the same
1710  * length timeseries, so find the minimum number of zeros to excise */
1711  if (nzeros) {
1712  j = 0;
1713  while (hlm->mode->data->data[hlm->mode->data->length - j - 1] == 0.0)
1714  ++j;
1715  if (j < nzeros)
1716  nzeros = j;
1717  }
1718 
1719  /* here is where we taper the beginning of the waveform below f_min */
1720  ntaper = round((extra_time_fraction * tchirp + textra) / deltaT);
1721  for (j = 0; j < ntaper; ++j)
1722  hlm->mode->data->data[j] *= 0.5 - 0.5 * cos(j * LAL_PI / ntaper);
1723 
1724  /* now high-pass filter the data at the original f_min value so that
1725  * the modes have negligible frequency content below that frequency;
1726  * note: this will cut off the low-frequency content of the m=1 mode */
1727  XLALHighPassCOMPLEX16TimeSeries(hlm->mode, original_f_min, 0.99, 8);
1728  }
1729 
1730  /* new length after clipping zeros from end */
1731  length -= nzeros;
1732  if (nzeros)
1733  XLALResizeSphHarmTimeSeries(modes, 0, length);
1734 
1735  /* stage 2 conditioning: final tapering at beginning and end */
1736  /* final tapering at the beginning and at the end */
1737  /* if this waveform is shorter than 2*min_taper_samples, do nothing */
1738  if (length < 2 * min_taper_samples) {
1739  XLAL_PRINT_WARNING("waveform is too shorter than %zu samples: no final tapering applied", 2 * min_taper_samples);
1740  return modes;
1741  }
1742 
1743  /* waveform should terminate at a frequency >= Schwarzschild ISCO
1744  * so taper one cycle at this frequency at the end; should not make
1745  * any difference to IMR waveforms */
1746  fisco = 1.0 / (pow(6.0, 1.5) * LAL_PI * (m1 + m2) * LAL_MTSUN_SI / LAL_MSUN_SI);
1747  ntaper = round(1.0 / (fisco * deltaT));
1748  if (ntaper < min_taper_samples)
1749  ntaper = min_taper_samples;
1750  for (hlm = modes; hlm; hlm = hlm->next)
1751  for (j = 1; j < ntaper; ++j)
1752  hlm->mode->data->data[length - j] *= 0.5 - 0.5 * cos(j * LAL_PI / ntaper);
1753 
1754  /* there could be a filter transient at the beginning too: we should have
1755  * some safety there owing to the fact that we are starting at a lower
1756  * frequency than is needed, so taper off one cycle at the low frequency */
1757  ntaper = round(1.0 / (f_min * deltaT));
1758  if (ntaper < min_taper_samples)
1759  ntaper = min_taper_samples;
1760  for (hlm = modes; hlm; hlm = hlm->next)
1761  for (j = 1; j < ntaper; ++j)
1762  hlm->mode->data->data[j] *= 0.5 - 0.5 * cos(j * LAL_PI / ntaper);
1763 
1764  return modes;
1765 }
1766 
1767 /**
1768  * Interface to compute a single -2 spin-weighted spherical harmonic mode
1769  * for a binary inspiral of any available amplitude and phase PN order.
1770  * The phasing is computed with any of the TaylorT1, T2, T3, T4 methods.
1771  */
1773  REAL8 deltaT, /**< sampling interval (s) */
1774  REAL8 m1, /**< mass of companion 1 (kg) */
1775  REAL8 m2, /**< mass of companion 2 (kg) */
1776  REAL8 f_min, /**< starting GW frequency (Hz) */
1777  REAL8 f_ref, /**< reference GW frequency (Hz) */
1778  REAL8 r, /**< distance of source (m) */
1779  REAL8 lambda1, /**< (tidal deformability of mass 1) / m1^5 (dimensionless) */
1780  REAL8 lambda2, /**< (tidal deformability of mass 2) / m2^5 (dimensionless) */
1781  LALSimInspiralWaveformFlags *waveFlags, /**< Set of flags to control special behavior of some waveform families. Pass in NULL (or None in python) for default flags */
1782  LALSimInspiralTestGRParam *nonGRparams, /**< Linked list of non-GR parameters. Pass in NULL (or None in python) for standard GR waveforms */
1783  int amplitudeO, /**< twice post-Newtonian amplitude order */
1784  int phaseO, /**< twice post-Newtonian order */
1785  int l, /**< l index of mode */
1786  int m, /**< m index of mode */
1787  Approximant approximant /**< post-Newtonian approximant to use for waveform production */
1788  )
1789 {
1790  REAL8 v0 = 1.;
1791  COMPLEX16TimeSeries *hlm;
1793 
1794  /* General sanity checks that will abort */
1795  /*
1796  * If non-GR approximants are added, change the below to
1797  * if( nonGRparams && approximant != nonGR1 && approximant != nonGR2 )
1798  */
1799  if( nonGRparams )
1800  {
1801  XLALPrintError("XLAL Error - %s: Passed in non-NULL pointer to LALSimInspiralTestGRParam for an approximant that does not use LALSimInspiralTestGRParam\n", __func__);
1803  }
1804 
1805  /* General sanity check the input parameters - only give warnings! */
1806  if( deltaT > 1. )
1807  XLALPrintWarning("XLAL Warning - %s: Large value of deltaT = %e requested.\nPerhaps sample rate and time step size were swapped?\n", __func__, deltaT);
1808  if( deltaT < 1./16385. )
1809  XLALPrintWarning("XLAL Warning - %s: Small value of deltaT = %e requested.\nCheck for errors, this could create very large time series.\n", __func__, deltaT);
1810  if( m1 < 0.09 * LAL_MSUN_SI )
1811  XLALPrintWarning("XLAL Warning - %s: Small value of m1 = %e (kg) = %e (Msun) requested.\nPerhaps you have a unit conversion error?\n", __func__, m1, m1/LAL_MSUN_SI);
1812  if( m2 < 0.09 * LAL_MSUN_SI )
1813  XLALPrintWarning("XLAL Warning - %s: Small value of m2 = %e (kg) = %e (Msun) requested.\nPerhaps you have a unit conversion error?\n", __func__, m2, m2/LAL_MSUN_SI);
1814  if( m1 + m2 > 1000. * LAL_MSUN_SI )
1815  XLALPrintWarning("XLAL Warning - %s: Large value of total mass m1+m2 = %e (kg) = %e (Msun) requested.\nSignal not likely to be in band of ground-based detectors.\n", __func__, m1+m2, (m1+m2)/LAL_MSUN_SI);
1816  if( f_min < 1. )
1817  XLALPrintWarning("XLAL Warning - %s: Small value of fmin = %e requested.\nCheck for errors, this could create a very long waveform.\n", __func__, f_min);
1818  if( f_min > 40.000001 )
1819  XLALPrintWarning("XLAL Warning - %s: Large value of fmin = %e requested.\nCheck for errors, the signal will start in band.\n", __func__, f_min);
1820 
1821  switch (approximant)
1822  {
1823  case TaylorT1:
1824  /* Waveform-specific sanity checks */
1826  XLALSimInspiralGetFrameAxis(waveFlags)) )
1827  XLAL_ERROR_NULL(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
1829  XLALSimInspiralGetModesChoice(waveFlags)) )
1830  XLAL_ERROR_NULL(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
1831  /* Call the waveform driver routine */
1833  deltaT, m1, m2, f_min, f_ref, r, lambda1, lambda2,
1834  XLALSimInspiralGetTidalOrder(waveFlags), amplitudeO,
1835  phaseO, l, m);
1836  break;
1837  case TaylorT2:
1838  /* Waveform-specific sanity checks */
1840  XLALSimInspiralGetFrameAxis(waveFlags)) )
1841  XLAL_ERROR_NULL(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
1843  XLALSimInspiralGetModesChoice(waveFlags)) )
1844  XLAL_ERROR_NULL(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
1845  /* Call the waveform driver routine */
1847  deltaT, m1, m2, f_min, f_ref, r, lambda1, lambda2,
1848  XLALSimInspiralGetTidalOrder(waveFlags), amplitudeO,
1849  phaseO, l, m);
1850  break;
1851  case TaylorT3:
1852  /* Waveform-specific sanity checks */
1854  XLAL_ERROR_NULL(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
1856  XLAL_ERROR_NULL(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
1857  /* Call the waveform driver routine */
1859  deltaT, m1, m2, f_min, f_ref, r, lambda1, lambda2,
1860  XLALSimInspiralGetTidalOrder(waveFlags), amplitudeO,
1861  phaseO, l, m);
1862  break;
1863  case TaylorT4:
1864  /* Waveform-specific sanity checks */
1866  XLALSimInspiralGetFrameAxis(waveFlags) ) )
1867  XLAL_ERROR_NULL(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
1869  XLALSimInspiralGetModesChoice(waveFlags) ) )
1870  XLAL_ERROR_NULL(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
1871  /* Call the waveform driver routine */
1873  deltaT, m1, m2, f_min, f_ref, r, lambda1, lambda2,
1874  XLALSimInspiralGetTidalOrder(waveFlags), amplitudeO,
1875  phaseO, l, m);
1876  break;
1877  case EOBNRv2:
1878  case EOBNRv2HM:
1879  ts = XLALSimIMREOBNRv2Modes(deltaT, m1, m2, f_min, r);
1881  break;
1882 
1883  default:
1884  XLALPrintError("Cannot generate modes for this approximant\n");
1886  }
1887  if ( !hlm )
1889 
1890  return hlm;
1891 }
1892 
1893 /** @} */
1894 
1895 /**
1896  * @name Routines for Generating Inspiral Waveforms from Orbital Data
1897  * @{
1898  */
1899 
1900 /**
1901  * Given time series for a binary's orbital dynamical variables,
1902  * construct the waveform polarizations h+ and hx directly.
1903  * NB: Valid only for non-precessing binaries!
1904  *
1905  * Implements Equations (8.8) - (8.10) of:
1906  * Luc Blanchet, Guillaume Faye, Bala R. Iyer and Siddhartha Sinha,
1907  * \"The third post-Newtonian gravitational wave polarisations
1908  * and associated spherical harmonic modes for inspiralling compact binaries
1909  * in quasi-circular orbits\", Class. Quant. Grav. 25 165003 (2008);
1910  * arXiv:0802.1249.
1911  * NB: Be sure to check arXiv:0802.1249v3, which corrects a typo!
1912  *
1913  * Note however, that we do not include the constant \"memory\" terms
1914  */
1916  REAL8TimeSeries **hplus, /**< +-polarization waveform [returned] */
1917  REAL8TimeSeries **hcross, /**< x-polarization waveform [returned] */
1918  REAL8TimeSeries *V, /**< post-Newtonian (PN) parameter */
1919  REAL8TimeSeries *Phi, /**< orbital phase */
1920  REAL8 v0, /**< tail-term gauge choice (default = 1) */
1921  REAL8 m1, /**< mass of companion 1 (kg) */
1922  REAL8 m2, /**< mass of companion 2 (kg) */
1923  REAL8 r, /**< distance of source (m) */
1924  REAL8 i, /**< inclination of source (rad) */
1925  int ampO /**< twice PN order of the amplitude */
1926  )
1927 {
1928  REAL8 M, eta, eta2, eta3, dm, dist, ampfac, phi, phiShift, v, v2, v3;
1929  REAL8 hp0, hp05, hp1, hp15, hp2, hp25, hp3;
1930  REAL8 hc0, hc05, hc1, hc15, hc2, hc25, hc3;
1931  REAL8 ci, si, ci2, ci4, ci6, ci8, si2, si3, si4, si5, si6;
1932  INT4 idx, len;
1933 
1934  /* Sanity check input time series */
1938 
1939  /* Allocate polarization vectors and set to 0 */
1940  *hplus = XLALCreateREAL8TimeSeries( "H_PLUS", &V->epoch, 0.0,
1941  V->deltaT, &lalStrainUnit, V->data->length );
1942  *hcross = XLALCreateREAL8TimeSeries( "H_CROSS", &V->epoch, 0.0,
1943  V->deltaT, &lalStrainUnit, V->data->length );
1944  if ( ! hplus || ! hcross )
1946  memset((*hplus)->data->data, 0, (*hplus)->data->length
1947  * sizeof(*(*hplus)->data->data));
1948  memset((*hcross)->data->data, 0, (*hcross)->data->length
1949  * sizeof(*(*hcross)->data->data));
1950 
1951  M = m1 + m2;
1952  eta = m1 * m2 / M / M; // symmetric mass ratio - '\nu' in the paper
1953  eta2 = eta*eta; eta3 = eta2*eta;
1954  dm = (m1 - m2) / M; // frac. mass difference - \delta m/m in the paper
1955  dist = r / LAL_C_SI; // r (m) / c (m/s) --> dist in units of seconds
1956  /* convert mass from kg to s, so ampfac ~ M/dist is dimensionless */
1957  ampfac = 2. * M * LAL_G_SI * pow(LAL_C_SI, -3) * eta / dist;
1958 
1959  /*
1960  * cosines and sines of inclination between
1961  * line of sight (N) and binary orbital angular momentum (L_N)
1962  */
1963  ci = cos(i); si = sin(i);
1964  ci2 = ci*ci; ci4 = ci2*ci2; ci6 = ci2*ci4; ci8 = ci6*ci2;
1965  si2 = si*si; si3 = si2*si; si4 = si2*si2; si5 = si*si4; si6 = si4*si2;
1966 
1967  /* loop over time steps and compute polarizations h+ and hx */
1968 
1969  len = V->data->length;
1970  for(idx = 0; idx < len; idx++)
1971  {
1972  /* Abbreviated names in lower case for time series at this sample */
1973  phi = Phi->data->data[idx]; v = V->data->data[idx];
1974  v2 = v * v; v3 = v * v2;
1975 
1976  /*
1977  * As explained in Blanchet et al, a phase shift can be applied
1978  * to make log terms vanish which would appear in the amplitude
1979  * at 1.5PN and 2.5PN orders. This shift is given in Eq. (8.8)
1980  * We apply the shift only for the PN orders which need it.
1981  */
1982  if( (ampO == -1) || ampO >= 5 )
1983  phiShift = 3.*v3*(1. - v2*eta/2.)*log( v2 / v0 / v0 );
1984  else if( ampO >= 3 )
1985  phiShift = 3.*v3*log( v2 / v0 / v0 );
1986  else
1987  phiShift = 0.;
1988 
1989  phi = phi - phiShift;
1990 
1991  /*
1992  * First set all h+/x coefficients to 0. Then use a switch to
1993  * set proper non-zero values up to order ampO. Note we
1994  * fall through the PN orders and break only after Newt. order
1995  */
1996  hp0 = hp05 = hp1 = hp15 = hp2 = hp25 = hp3 = 0.;
1997  hc0 = hc05 = hc1 = hc15 = hc2 = hc25 = hc3 = 0.;
1998 
1999  switch( ampO )
2000  {
2001  /* case LAL_PNORDER_THREE_POINT_FIVE: */
2002  case 7:
2003  XLALPrintError("XLAL Error - %s: Amp. corrections not known "
2004  "to PN order %d\n", __func__, ampO );
2006  break;
2007  case -1: // Highest known PN order - move if higher terms added!
2008  /* case LAL_PNORDER_THREE: */
2009  case 6:
2010  /* The reference had a typo in the 3PN terms and needed an errata.
2011  * These should match arXiv:0802.1249v3, which has the fix. */
2012  hp3 = LAL_PI*dm*si*cos(phi)*(19./64. + ci2*5./16. - ci4/192.
2013  + eta*(-19./96. + ci2*3./16. + ci4/96.)) + cos(2.*phi)
2014  * (-465497./11025. + (LAL_GAMMA*856./105.
2015  - 2.*LAL_PI*LAL_PI/3. + log(16.*v2)*428./105.)
2016  * (1. + ci2) - ci2*3561541./88200. - ci4*943./720.
2017  + ci6*169./720. - ci8/360. + eta*(2209./360.
2018  - LAL_PI*LAL_PI*41./96.*(1. + ci2) + ci2*2039./180.
2019  + ci4*3311./720. - ci6*853./720. + ci8*7./360.)
2020  + eta2*(12871./540. - ci2*1583./60. - ci4*145./108.
2021  + ci6*56./45. - ci8*7./180.) + eta3*(-3277./810.
2022  + ci2*19661./3240. - ci4*281./144. - ci6*73./720.
2023  + ci8*7./360.)) + LAL_PI*dm*si*cos(3.*phi)*(-1971./128.
2024  - ci2*135./16. + ci4*243./128. + eta*(567./64.
2025  - ci2*81./16. - ci4*243./64.)) + si2*cos(4.*phi)
2026  * (-2189./210. + ci2*1123./210. + ci4*56./9.
2027  - ci6*16./45. + eta*(6271./90. - ci2*1969./90.
2028  - ci4*1432./45. + ci6*112./45.) + eta2*(-3007./27.
2029  + ci2*3493./135. + ci4*1568./45. - ci6*224./45.)
2030  + eta3*(161./6. - ci2*1921./90. - ci4*184./45.
2031  + ci6*112./45.)) + dm*cos(5.*phi)*(LAL_PI*3125./384.
2032  * si3*(1. + ci2)*(1. - 2.*eta)) + si4*cos(6.*phi)
2033  * (1377./80. + ci2*891./80. - ci4*729./280.
2034  + eta*(-7857./80. - ci2*891./16. + ci4*729./40.)
2035  + eta2*(567./4. + ci2*567./10. - ci4*729./20.)
2036  + eta3*(-729./16. - ci2*243./80. + ci4*729./40.))
2037  + cos(8.*phi)*(-1024./315.*si6*(1. + ci2)*(1. - 7.*eta
2038  + 14.*eta2 - 7.*eta3)) + dm*si*sin(phi)*(-2159./40320.
2039  - log(2.)*19./32. + (-95./224. - log(2.)*5./8.)*ci2
2040  + (181./13440. + log(2.)/96.)*ci4 + eta*(1369./160.
2041  + log(2.)*19./48. + (-41./48. - log(2.)*3./8.)*ci2
2042  + (-313./480. - log(2.)/48.)*ci4)) + sin(2.*phi)
2043  * (-428.*LAL_PI/105.*(1. + ci2)) + dm*si*sin(3.*phi)
2044  * (205119./8960. - log(3./2.)*1971./64.
2045  + (1917./224. - log(3./2.)*135./8.)*ci2
2046  + (-43983./8960. + log(3./2.)*243./64.)*ci4 + eta
2047  * (-54869./960. + log(3./2.)*567./32.
2048  + (-923./80. - log(3./2.)*81./8.)*ci2
2049  + (41851./2880. - log(3./2.)*243./32.)*ci4))
2050  + dm*si3*(1. + ci2)*sin(5.*phi)*(-113125./5376.
2051  + log(5./2.)*3125./192.
2052  + eta*(17639./320. - log(5./2.)*3125./96.));
2053  hc3 = dm*si*ci*cos(phi)*(11617./20160. + log(2.)*21./16.
2054  + (-251./2240. - log(2.)*5./48.)*ci2
2055  + eta*(-2419./240. - log(2.)*5./24.
2056  + (727./240. + log(2.)*5./24.)*ci2)) + ci*cos(2.*phi)
2057  * (LAL_PI*856./105.) + dm*si*ci*cos(3.*phi)
2058  * (-36801./896. + log(3./2.)*1809./32.
2059  + (65097./4480. - log(3./2.)*405./32.)*ci2
2060  + eta*(28445./288. - log(3./2.)*405./16.
2061  + (-7137./160. + log(3./2.)*405./16.)*ci2))
2062  + dm*si3*ci*cos(5.*phi)*(113125./2688.
2063  - log(5./2.)*3125./96. + eta*(-17639./160.
2064  + log(5./2.)*3125./48.)) + LAL_PI*dm*si*ci*sin(phi)
2065  * (21./32. - ci2*5./96. + eta*(-5./48. + ci2*5./48.))
2066  + ci*sin(2.*phi)*(-3620761./44100.
2067  + LAL_GAMMA*1712./105. - 4.*LAL_PI*LAL_PI/3.
2068  + log(16.*v2)*856./105. - ci2*3413./1260.
2069  + ci4*2909./2520. - ci6/45. + eta*(743./90.
2070  - 41.*LAL_PI*LAL_PI/48. + ci2*3391./180.
2071  - ci4*2287./360. + ci6*7./45.) + eta2*(7919./270.
2072  - ci2*5426./135. + ci4*382./45. - ci6*14./45.)
2073  + eta3*(-6457./1620. + ci2*1109./180. - ci4*281./120.
2074  + ci6*7./45.)) + LAL_PI*dm*si*ci*sin(3.*phi)
2075  * (-1809./64. + ci2*405./64. + eta*(405./32.
2076  - ci2*405./32.)) + si2*ci*sin(4.*phi)*(-1781./105.
2077  + ci2*1208./63. - ci4*64./45. + eta*(5207./45.
2078  - ci2*536./5. + ci4*448./45.) + eta2*(-24838./135.
2079  + ci2*2224./15. - ci4*896./45.) + eta3*(1703./45.
2080  - ci2*1976./45. + ci4*448./45.)) + dm*sin(5.*phi)
2081  * (3125.*LAL_PI/192.*si3*ci*(1. - 2.*eta))
2082  + si4*ci*sin(6.*phi)*(9153./280. - ci2*243./35.
2083  + eta*(-7371./40. + ci2*243./5.) + eta2*(1296./5.
2084  - ci2*486./5.) + eta3*(-3159./40. + ci2*243./5.))
2085  + sin(8.*phi)*(-2048./315.*si6*ci*(1. - 7.*eta
2086  + 14.*eta2 - 7.*eta3));
2087 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2088  __attribute__ ((fallthrough));
2089 #endif
2090  /* case LAL_PNORDER_TWO_POINT_FIVE: */
2091  case 5:
2092  hp25 = cos(phi)*si*dm*(1771./5120. - ci2*1667./5120.
2093  + ci4*217./9216. - ci6/9126. + eta*(681./256.
2094  + ci2*13./768. - ci4*35./768. + ci6/2304.)
2095  + eta2*(-3451./9216. + ci2*673./3072. - ci4*5./9216.
2096  - ci6/3072.)) + cos(2.*phi)*LAL_PI*(19./3. + 3.*ci2
2097  - ci4*2./3. + eta*(-16./3. + ci2*14./3. + 2.*ci4))
2098  + cos(3.*phi)*si*dm*(3537./1024. - ci2*22977./5120.
2099  - ci4*15309./5120. + ci6*729./5120.
2100  + eta*(-23829./1280. + ci2*5529./1280.
2101  + ci4*7749./1280. - ci6*729./1280.)
2102  + eta2*(29127./5120. - ci2*27267./5120.
2103  - ci4*1647./5120. + ci6*2187./5120.)) + cos(4.*phi)
2104  * (-16.*LAL_PI/3.*(1. + ci2)*si2*(1. - 3.*eta))
2105  + cos(5.*phi)*si*dm*(-108125./9216. + ci2*40625./9216.
2106  + ci4*83125./9216. - ci6*15625./9216.
2107  + eta*(8125./256. - ci2*40625./2304. - ci4*48125./2304.
2108  + ci6*15625./2304.) + eta2*(-119375./9216.
2109  + ci2*40625./3072. + ci4*44375./9216.
2110  - ci6*15625./3072.)) + cos(7.*phi)*dm
2111  * (117649./46080.*si5*(1. + ci2)*(1. - 4.*eta
2112  + 3.*eta2)) + sin(2.*phi)*(-9./5. + ci2*14./5.
2113  + ci4*7./5. + eta*(32. + ci2*56./5. - ci4*28./5.))
2114  + sin(4.*phi)*si2*(1. + ci2)*(56./5. - 32.*log(2.)/3.
2115  + eta*(-1193./30. + 32.*log(2.)));
2116  /* below would have a constant memory term of si2*ci*eta*6./5. */
2117  hc25 = cos(2.*phi)*ci*(2. - ci2*22./5. + eta*(-282./5.
2118  + ci2*94./5.)) + cos(4.*phi)*ci*si2*(-112./5.
2119  + 64.*log(2.)/3. + eta*(1193./15. - 64.*log(2.)))
2120  + sin(phi)*si*ci*dm*(-913./7680. + ci2*1891./11520.
2121  - ci4*7./4608. + eta*(1165./384. - ci2*235./576.
2122  + ci4*7./1152.) + eta2*(-1301./4608. + ci2*301./2304.
2123  - ci4*7./1536.)) + sin(2.*phi)*LAL_PI*ci*(34./3.
2124  - ci2*8./3. + eta*(-20./3. + 8.*ci2))
2125  + sin(3.*phi)*si*ci*dm*(12501./2560. - ci2*12069./1280.
2126  + ci4*1701./2560. + eta*(-19581./640. + ci2*7821./320.
2127  - ci4*1701./640.) + eta2*(18903./2560.
2128  - ci2*11403./1280. + ci4*5103./2560.))
2129  + sin(4.*phi)*si2*ci*(-32.*LAL_PI/3.*(1. - 3.*eta))
2130  + sin(5.*phi)*si*ci*dm*(-101875./4608. + ci2*6875./256.
2131  - ci4*21875./4608. + eta*(66875./1152.
2132  - ci2*44375./576. + ci4*21875./1152.)
2133  + eta2*(-100625./4608. + ci2*83125./2304.
2134  - ci4*21875./1536.)) + sin(7.*phi)*si5*ci*dm
2135  * (117649./23040.*(1. - 4.*eta + 3.*eta2));
2136 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2137  __attribute__ ((fallthrough));
2138 #endif
2139  /* case LAL_PNORDER_TWO: */
2140  case 4:
2141  hp2 = cos(phi)*LAL_PI*si*dm*(-5./8. - ci2/8.)
2142  + cos(2.*phi)*(11./60. + ci2*33./10. + ci4*29./24.
2143  - ci6/24. + eta*(353./36. - 3.*ci2 - ci4*251./72.
2144  + ci6*5./24.) + eta2*(-49./12. + ci2*9./2.
2145  - ci4*7./24. - ci6*5./24.)) + cos(3.*phi)*LAL_PI*si*dm
2146  * (27./8.*(1 + ci2)) + cos(4.*phi)*si2*2./15.*(59.
2147  + ci2*35. - ci4*8.
2148  - eta*5./3.*(131. + 59.*ci2 + 24.*ci4)
2149  + eta2*5.*(21. - 3.*ci2 - 8.*ci4))
2150  + cos(6.*phi)*(-81./40.*si4*(1. + ci2)
2151  * (1. - 5.*eta + 5.*eta2)) + sin(phi)*si*dm
2152  * (11./40. + 5.*log(2)/4. + ci2*(7./40. + log(2)/4.))
2153  + sin(3.*phi)*si*dm*((-189./40. + 27./4.*log(3./2.))
2154  * (1. + ci2));
2155  hc2 = cos(phi)*si*ci*dm*(-9./20. - 3./2.*log(2.))
2156  + cos(3.*phi)*si*ci*dm*(189./20. - 27./2.*log(3./2.))
2157  - sin(phi)*si*ci*dm*3.*LAL_PI/4.
2158  + sin(2.*phi)*ci*(17./15. + ci2*113./30. - ci4/4.
2159  + eta*(143./9. - ci2*245./18. + ci4*5./4.)
2160  + eta2*(-14./3. + ci2*35./6. - ci4*5./4.))
2161  + sin(3.*phi)*si*ci*dm*27.*LAL_PI/4.
2162  + sin(4.*phi)*ci*si2*4./15.*(55. - 12.*ci2
2163  - eta*5./3.*(119. - 36.*ci2)
2164  + eta2*5.*(17. - 12.*ci2))
2165  + sin(6.*phi)*ci*(-81./20.*si4
2166  * (1. - 5.*eta + 5.*eta2));
2167 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2168  __attribute__ ((fallthrough));
2169 #endif
2170  /* case LAL_PNORDER_ONE_POINT_FIVE: */
2171  case 3:
2172  hp15 = cos(phi)*si*dm*(19./64. + ci2*5./16. - ci4/192.
2173  + eta*(-49./96. + ci2/8. + ci4/96.))
2174  + cos(2.*phi)*(-2.*LAL_PI*(1. + ci2))
2175  + cos(3.*phi)*si*dm*(-657./128. - ci2*45./16.
2176  + ci4*81./128. + eta*(225./64. - ci2*9./8.
2177  - ci4*81./64.)) + cos(5.*phi)*si*dm*(625./384.*si2
2178  * (1. + ci2)*(1. - 2.*eta));
2179  hc15 = sin(phi)*si*ci*dm*(21./32. - ci2*5./96.
2180  + eta*(-23./48. + ci2*5./48.))
2181  - 4.*LAL_PI*ci*sin(2.*phi) + sin(3.*phi)*si*ci*dm
2182  * (-603./64. + ci2*135./64.
2183  + eta*(171./32. - ci2*135./32.))
2184  + sin(5.*phi)*si*ci*dm*(625./192.*si2*(1. - 2.*eta));
2185 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2186  __attribute__ ((fallthrough));
2187 #endif
2188  /* case LAL_PNORDER_ONE: */
2189  case 2:
2190  hp1 = cos(2.*phi)*(19./6. + 3./2.*ci2 - ci4/3.
2191  + eta*(-19./6. + ci2*11./6. + ci4))
2192  - cos(4.*phi) * (4./3.*si2*(1. + ci2)*(1. - 3.*eta));
2193  hc1 = sin(2.*phi)*ci*(17./3. - ci2*4./3.
2194  + eta*(-13./3. + 4.*ci2))
2195  + sin(4.*phi)*ci*si2*(-8./3.*(1. - 3.*eta));
2196 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2197  __attribute__ ((fallthrough));
2198 #endif
2199  /*case LAL_PNORDER_HALF:*/
2200  case 1:
2201  hp05 = - si*dm*(cos(phi)*(5./8. + ci2/8.)
2202  - cos(3.*phi)*(9./8. + 9.*ci2/8.));
2203  hc05 = si*ci*dm*(-sin(phi)*3./4. + sin(3.*phi)*9./4.);
2204 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
2205  __attribute__ ((fallthrough));
2206 #endif
2207  case 0:
2208  /* below would have a constant memory term of -si2/96.*(17. + ci2) */
2209  hp0 = -(1. + ci2)*cos(2.*phi);
2210  hc0 = -2.*ci*sin(2.*phi);
2211  break;
2212  /*case LAL_PNORDER_NEWTONIAN:*/
2213  default:
2214  XLALPrintError("XLAL Error - %s: Invalid amp. PN order %d\n",
2215  __func__, ampO );
2217  break;
2218  } /* End switch on ampO */
2219 
2220  /* Fill the output polarization arrays */
2221  (*hplus)->data->data[idx] = ampfac * v2 * ( hp0 + v * ( hp05
2222  + v * ( hp1 + v * ( hp15 + v * ( hp2 + v * ( hp25 + v * hp3
2223  ) ) ) ) ) );
2224  (*hcross)->data->data[idx] = ampfac * v2 * ( hc0 + v * ( hc05
2225  + v * ( hc1 + v * ( hc15 + v * ( hc2 + v * ( hc25 + v * hc3
2226  ) ) ) ) ) );
2227 
2228  } /* end loop over time series samples idx */
2229  return XLAL_SUCCESS;
2230 }
2231 /** @} */
2232 
2233 /**
2234  * Given time series for a binary's orbital dynamical variables,
2235  * construct the waveform polarizations h+ and hx as a sum of
2236  * -2 spin-weighted spherical harmonic modes, h_lm.
2237  * NB: Valid only for non-precessing systems!
2238  *
2239  * Implements Equation (11) of:
2240  * Lawrence E. Kidder, \"Using Full Information When Computing Modes of
2241  * Post-Newtonian Waveforms From Inspiralling Compact Binaries in Circular
2242  * Orbit\", Physical Review D 77, 044016 (2008), arXiv:0710.0614v1 [gr-qc].
2243  */
2245  REAL8TimeSeries **hplus, /**< +-polarization waveform [returned] */
2246  REAL8TimeSeries **hcross, /**< x-polarization waveform [returned] */
2247  REAL8TimeSeries *v, /**< post-Newtonian parameter */
2248  REAL8TimeSeries *phi, /**< orbital phase */
2249  REAL8 v0, /**< tail-term gauge choice (default = 1) */
2250  REAL8 m1, /**< mass of companion 1 */
2251  REAL8 m2, /**< mass of companion 2 */
2252  REAL8 r, /**< distance of source */
2253  REAL8 i, /**< inclination of source (rad) */
2254  int O /**< twice post-Newtonian order */
2255  )
2256 {
2257  int l, m;
2261  *hplus = XLALCreateREAL8TimeSeries( "H_PLUS", &v->epoch, 0.0, v->deltaT, &lalStrainUnit, v->data->length );
2262  *hcross = XLALCreateREAL8TimeSeries( "H_CROSS", &v->epoch, 0.0, v->deltaT, &lalStrainUnit, v->data->length );
2263  if ( ! hplus || ! hcross )
2265  memset((*hplus)->data->data, 0, (*hplus)->data->length*sizeof(*(*hplus)->data->data));
2266  memset((*hcross)->data->data, 0, (*hcross)->data->length*sizeof(*(*hcross)->data->data));
2267  for ( l = 2; l <= LAL_PN_MODE_L_MAX; ++l ) {
2268  for ( m = 1; m <= l; ++m ) {
2269  COMPLEX16TimeSeries *hmode;
2270  hmode = XLALCreateSimInspiralPNModeCOMPLEX16TimeSeries(v, phi, v0, m1, m2, r, O, l, m);
2271  if ( ! hmode )
2273  if ( XLALSimAddMode(*hplus, *hcross, hmode, i, 0.0, l, m, 1) < 0 )
2276  }
2277  }
2278  return 0;
2279 }
2280 
2281 /**
2282  * Compute the polarizations from all the -2 spin-weighted spherical harmonic
2283  * modes stored in 'hlms'. Be sure that 'hlms' is the head of the linked list!
2284  *
2285  * The computation done is:
2286  * \f$hp(t) - i hc(t) = \sum_l \sum_m h_lm(t) -2Y_lm(iota,psi)\f$
2287  *
2288  * iota and psi are the inclination and polarization angle of the observer
2289  * relative to the source of GWs.
2290  */
2292  REAL8TimeSeries **hp, /**< Plus polarization time series [returned] */
2293  REAL8TimeSeries **hc, /**< Cross polarization time series [returned] */
2294  SphHarmTimeSeries *hlms, /**< Head of linked list of waveform modes */
2295  REAL8 iota, /**< inclination of viewer to source frame (rad) */
2296  REAL8 phiRef /**< reference phase (rad) */
2297  )
2298 {
2299  int ret;
2300  SphHarmTimeSeries *ts = hlms;
2301  size_t length = ts->mode->data->length;
2302  // Destroy hp, hc TimeSeries if they already exist
2303  if( (*hp) ) XLALDestroyREAL8TimeSeries( *hp );
2304  if( (*hc) ) XLALDestroyREAL8TimeSeries( *hc );
2305  *hp = XLALCreateREAL8TimeSeries("hplus", &(ts->mode->epoch), ts->mode->f0,
2306  ts->mode->deltaT, &lalStrainUnit, length);
2307  *hc = XLALCreateREAL8TimeSeries("hplus", &(ts->mode->epoch), ts->mode->f0,
2308  ts->mode->deltaT, &lalStrainUnit, length);
2309  memset( (*hp)->data->data, 0, (*hp)->data->length*sizeof(REAL8) );
2310  memset( (*hc)->data->data, 0, (*hc)->data->length*sizeof(REAL8) );
2311  while (ts) { // Add the contribution from the current mode to hp, hx...
2312  // This function adds hlm(t) * Y_lm(incl,phiRef) to (h+ - i hx)(t)
2313  ret = XLALSimAddMode(*hp, *hc, ts->mode, iota, phiRef, ts->l, ts->m, 0);
2314  if( ret != XLAL_SUCCESS ) XLAL_ERROR(XLAL_EFUNC);
2315  ts = ts->next;
2316  }
2317 
2318  return XLAL_SUCCESS;
2319 }
2320 
2321 
2322 /**
2323  Function returning the Fourier domain polarizations for positive frequencies built from the individual modes computed with ChooseFDModes.
2324  The output should be equivalent to that from ChooseFDWaveform, close to machine precision.
2325  Some of the AS models use the argument phiRef internally to build the hlms and build the polarizations with an azimuthal angle different from Pi/2 - phiRef.
2326  In this function we take into account those differences among models.
2327  For the precessing model IMRPhenomXPHM, since the modes are returned in the J-frame, the polarizations are built using theta_JN instead of the inclination and azimuthal angle = 0.
2328 */
2330  COMPLEX16FrequencySeries **hptilde, /**< FD plus polarization */
2331  COMPLEX16FrequencySeries **hctilde, /**< FD cross polarization */
2332  const REAL8 m1, /**< mass of companion 1 (kg) */
2333  const REAL8 m2, /**< mass of companion 2 (kg) */
2334  const REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
2335  const REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
2336  const REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
2337  const REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
2338  const REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
2339  const REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
2340  const REAL8 distance, /**< distance of source (m) */
2341  const REAL8 inclination, /**< inclination of source (rad) */
2342  const REAL8 phiRef, /**< reference orbital phase (rad) */
2343  const REAL8 UNUSED longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
2344  const REAL8 UNUSED eccentricity, /**< eccentricity at reference epoch */
2345  const REAL8 UNUSED meanPerAno, /**< mean anomaly of periastron */
2346  // frequency sampling parameters, no default value
2347  const REAL8 deltaF, /**< sampling interval (Hz) */
2348  const REAL8 f_min, /**< starting GW frequency (Hz) */
2349  const REAL8 f_max, /**< ending GW frequency (Hz) */
2350  REAL8 f_ref, /**< Reference frequency (Hz) */
2351  LALDict *LALparams, /**< LAL dictionary containing accessory parameters */
2352  const Approximant approximant /**< post-Newtonian approximant to use for waveform production */
2353  )
2354 {
2355 
2356  /* Adjust the reference frequency for certain precessing approximants:
2357  * if that approximate interprets f_ref==0 to be f_min, set f_ref=f_min;
2358  * otherwise do nothing */
2360 
2361  int ret = XLAL_SUCCESS;
2362  REAL8 phiRef_modes = 0;
2363  REAL8 theta = inclination;
2364  REAL8 azimuthal = LAL_PI_2 - phiRef;
2365  REAL8 zeta_polarization = 0;
2366 
2367  switch (approximant)
2368  {
2369  case IMRPhenomXHM:
2370  phiRef_modes = phiRef;
2371  azimuthal = LAL_PI_2;
2372  break;
2373 
2374  case IMRPhenomXPHM:
2375  phiRef_modes = phiRef;
2376  REAL8 d1=0, d2=0, d3=0, d4=0, d5=0;
2377  ret = XLALSimIMRPhenomXPCalculateModelParametersFromSourceFrame(&d1, &d2, &d3, &theta, &d4, &d5, &zeta_polarization, m1, m2, f_ref, phiRef, inclination, S1x,S1y,S1z, S2x,S2y,S2z, LALparams);
2378  XLAL_CHECK(XLAL_SUCCESS == ret, XLAL_EFUNC, "Error: XLALSimIMRPhenomXPCalculateModelParametersFromSourceFrame failed.\n");
2379  azimuthal = 0.;
2380 
2381  break;
2382  case IMRPhenomXO4a:
2383  phiRef_modes = phiRef;
2384  d1=0, d2=0, d3=0, d4=0, d5=0;
2385  ret = XLALSimIMRPhenomXPCalculateModelParametersFromSourceFrame(&d1, &d2, &d3, &theta, &d4, &d5, &zeta_polarization, m1, m2, f_ref, phiRef, inclination, S1x,S1y,S1z, S2x,S2y,S2z, LALparams);
2386  XLAL_CHECK(XLAL_SUCCESS == ret, XLAL_EFUNC, "Error: XLALSimIMRPhenomXPCalculateModelParametersFromSourceFrame failed.\n");
2387  azimuthal = 0.;
2388  break;
2389  case SEOBNRv4HM_ROM:
2390 
2391  break;
2392  case SEOBNRv5_ROM:
2393 
2394  break;
2395  case SEOBNRv5HM_ROM:
2396 
2397  break;
2398  case IMRPhenomHM:
2399  phiRef_modes = phiRef;
2400  break;
2401  default:
2402  XLALPrintError("Approximant not implemented\n");
2404  }
2405 
2406 
2408  *hlms = XLALSimInspiralChooseFDModes(m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, deltaF, f_min, f_max, f_ref, phiRef_modes, distance, inclination, LALparams, approximant);
2409  if(!(*hlms)){
2410  XLAL_ERROR(XLAL_EFUNC, "Error: XLALSimInspiralChooseFDModes failed\n");
2411  }
2412 
2413  UINT4 len = (*hlms)->mode->data->length;
2414  UINT4 offset = 0;
2415 
2416  /* This is to account that ChooseFDModes return the modes for both negative and positve frequencies,
2417  but here we return the polarizations just for positive frequencies. */
2418  len = (UINT4) ceil(len/2.);
2419  offset = len-1;
2420 
2421  /* Create polarizations objects */
2422  *hptilde = XLALCreateCOMPLEX16FrequencySeries("FD hplus",
2423  &((*hlms)->mode->epoch), (*hlms)->mode->f0, (*hlms)->mode->deltaF,
2424  &((*hlms)->mode->sampleUnits), len);
2425  *hctilde = XLALCreateCOMPLEX16FrequencySeries("FD hcross",
2426  &((*hptilde)->epoch), (*hptilde)->f0, (*hptilde)->deltaF,
2427  &((*hptilde)->sampleUnits), (*hptilde)->data->length);
2428  memset((*hptilde)->data->data, 0, (len) * sizeof(COMPLEX16));
2429  memset((*hctilde)->data->data, 0, (len) * sizeof(COMPLEX16));
2430 
2431 
2432  SphHarmFrequencySeries *hlms_tmp = *hlms;
2433 
2434  /* Build the polarizations by summing the modes*/
2435  while ( hlms_tmp ){
2436  COMPLEX16 Ylm = XLALSpinWeightedSphericalHarmonic(theta, azimuthal, -2, hlms_tmp->l, hlms_tmp->m);
2437  COMPLEX16 Ylmstar = conj(Ylm);
2438 
2439  for(UINT4 idx = 0; idx<len; idx++){
2440  COMPLEX16 hlm = hlms_tmp->mode->data->data[idx + offset];
2441  COMPLEX16 hlm2 = conj(hlms_tmp->mode->data->data[len - 1 - idx]);
2442  (*hptilde)->data->data[idx] += 0.5 * (hlm * Ylm + hlm2 * Ylmstar);
2443  (*hctilde)->data->data[idx] += 0.5 * I * (hlm * Ylm - hlm2 * Ylmstar);
2444  }
2445  hlms_tmp = hlms_tmp->next;
2446  }
2447 
2448  /* Free memory */
2450  XLALFree(hlms);
2452 
2453 
2454  /* Add the correct polarization angle for IMRPhenomXPHM */
2455  if(fabs(zeta_polarization) > 0)
2456  {
2457  COMPLEX16 PhPpolp, PhPpolc;
2458  REAL8 cosPolFac, sinPolFac;
2459 
2460  cosPolFac = cos(2.0 * zeta_polarization);
2461  sinPolFac = sin(2.0 * zeta_polarization);
2462 
2463  for (UINT4 i = 0; i < (*hptilde)->data->length; i++)
2464  {
2465  PhPpolp = (*hptilde)->data->data[i];
2466  PhPpolc = (*hctilde)->data->data[i];
2467 
2468  (*hptilde)->data->data[i] = cosPolFac * PhPpolp + sinPolFac * PhPpolc;
2469  (*hctilde)->data->data[i] = cosPolFac * PhPpolc - sinPolFac * PhPpolp;
2470  }
2471  }
2472 
2473 
2474  /* This final rotation is taken from ChooseFDWaveform */
2475  REAL8 polariz=longAscNodes;
2476  if (polariz) {
2477  COMPLEX16 tmpP,tmpC;
2478  for (UINT4 idx=0;idx<(*hptilde)->data->length;idx++) {
2479 tmpP=(*hptilde)->data->data[idx];
2480 tmpC=(*hctilde)->data->data[idx];
2481 (*hptilde)->data->data[idx] =cos(2.*polariz)*tmpP+sin(2.*polariz)*tmpC;
2482 (*hctilde)->data->data[idx]=cos(2.*polariz)*tmpC-sin(2.*polariz)*tmpP;
2483  }
2484  }
2485 
2486  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
2488  ret = XLALSimLorentzInvarianceViolationTerm(hptilde, hctilde, m1/LAL_MSUN_SI, m2/LAL_MSUN_SI, distance, LALparams);
2489  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
2490 
2491  return ret;
2492 }
2493 
2494 
2495 
2496 /**
2497  Return polarizations for positive frequencies built by summing the individual modes present
2498  in the input array SphHarmFrequencySeries *hlms computed with ChooseFDModes.
2499  Notice that in general the output may not be close to machine precision with ChooseFDWaveform due to differences in
2500  computing the h_lms and in the use of the azimuthal angle.
2501  For IMRPhenomXPHM, the argument theta should not be the inclination but theta_JN and phiRef should be 0.
2502 */
2504  COMPLEX16FrequencySeries **hp, /**< Plus polarization frequency series [returned] */
2505  COMPLEX16FrequencySeries **hc, /**< Cross polarization frequency series [returned] */
2506  SphHarmFrequencySeries *hlms, /**< Head of linked list of waveform modes */
2507  REAL8 theta, /**< Polar angle for the Ylms (rad): Inclination for h_lms in L0-frame and theta_JN for J-frame. */
2508  REAL8 phi /**< Azimuthal angle for the Ylms (rad): pi/2 - phiRef for AS models and 0 for precessing. */
2509  )
2510 {
2511  if (!(hlms)){ XLAL_ERROR(XLAL_EFUNC, "SphHarmFrequencySeires object empty.\n");}
2512 
2513  SphHarmFrequencySeries *fs = hlms;
2514  UINT4 len = fs->mode->data->length;
2515  INT4 offset = 0;
2516  /* This is to account that ChooseFDModes return the modes for both negative and positve frequencies,
2517  but here we return the polarizations just for positive frequencies. */
2518  len = (UINT4) ceil(len/2.);
2519  offset = len-1;
2520  // Destroy hp, hc FrequencySeries if they already exist
2521  if( (*hp) ) XLALDestroyCOMPLEX16FrequencySeries( *hp );
2522  if( (*hc) ) XLALDestroyCOMPLEX16FrequencySeries( *hc );
2523  *hp = XLALCreateCOMPLEX16FrequencySeries("hplus", &(fs->mode->epoch), fs->mode->f0,
2524  fs->mode->deltaF, &(fs->mode->sampleUnits), len);
2525  *hc = XLALCreateCOMPLEX16FrequencySeries("hcross", &(fs->mode->epoch), fs->mode->f0,
2526  fs->mode->deltaF, &(fs->mode->sampleUnits), len);
2527  memset( (*hp)->data->data, 0, (*hp)->data->length*sizeof(COMPLEX16) );
2528  memset( (*hc)->data->data, 0, (*hc)->data->length*sizeof(COMPLEX16) );
2529 
2530 
2531  /* Build the polarizations by summing the modes */
2532  while ( fs ){
2533  COMPLEX16 Ylm = XLALSpinWeightedSphericalHarmonic(theta, phi, -2, fs->l, fs->m);
2534  COMPLEX16 Ylmstar = conj(Ylm);
2535 
2536  for(UINT4 idx = 0; idx<len; idx++){
2537  COMPLEX16 hlm = fs->mode->data->data[idx + offset];
2538  COMPLEX16 hlm2 = conj(fs->mode->data->data[len - 1 - idx]);
2539  (*hp)->data->data[idx] += 0.5 * (hlm * Ylm + hlm2 * Ylmstar);
2540  (*hc)->data->data[idx] += 0.5 * I * (hlm * Ylm - hlm2 * Ylmstar);
2541  }
2542  fs = fs->next;
2543  }
2545 
2546  return XLAL_SUCCESS;
2547 }
2548 
2549 
2550 /**
2551  * Given time series for a binary's orbital dynamical variables,
2552  * computes the radial and angular orbital motion; then constructs
2553  * the waveform polarizations h+ and hx in terms of the relative
2554  * separation r, the `true anomaly` phi and their time derivatives.
2555  * NB: Valid only for non-spinning binaries in inspiralling!
2556  * and precessing eccentric orbits!
2557  *
2558  * Implements Equations (3.7a) - (3.7c) and Equations (B2a) - (B2d), (B4a), (B4b) of:
2559  * Sashwat Tanay, Maria Haney, and Achamveedu Gopakumar,
2560  * \"Frequency and time domain inspiral waveforms from comparable
2561  * mass compact binaries in eccentric orbits\", (2015);
2562  * arXiv:TBD
2563  * https://dcc.ligo.org/P1500148-v1
2564  *
2565  * (note that above equations use x = v^2 as the PN expansion parameter)
2566  *
2567  * as well as Equations (6a) and (6b) of:
2568  * Thibault Damour, Achamveedu Gopakumar, and Bala R. Iyer,
2569  * \"Phasing of gravitational waves from inspiralling eccentric
2570  * binaries\", Phys. Rev. D 70 064028 (2004);
2571  * arXiv:gr-qc/0404128.
2572  */
2574  REAL8TimeSeries **hplus, /**< +-polarization waveform [returned] */
2575  REAL8TimeSeries **hcross, /**< x-polarization waveform [returned] */
2576  REAL8TimeSeries *V, /**< post-Newtonian (PN) parameter */
2577  REAL8TimeSeries *Ecc, /**< orbital eccentricity */
2578  REAL8TimeSeries *U, /**< eccentric anomaly of quasi-Keplerian orbit */
2579  REAL8TimeSeries *Phi, /**< orbital phase */
2580  REAL8 m1, /**< mass of companion 1 (kg) */
2581  REAL8 m2, /**< mass of companion 2 (kg) */
2582  REAL8 r, /**< distance of source (m) */
2583  REAL8 i, /**< inclination of source (rad) */
2584  int ampO, /**< twice PN order of the amplitude */
2585  int ph_O /**< twice PN order of the phase */
2586  )
2587 {
2588  REAL8 mt, eta, dist, ampfac, phi, v, et, u;
2589  REAL8 dt, OTS;
2590  REAL8 CF_rdot, CF_rphidot, CF_Z, r_sc, rdot_sc, phidot;
2591  REAL8 rdot, rphidot, Z;
2592  REAL8 hp0;
2593  REAL8 hc0;
2594  REAL8 ci, si, ci2, si2;
2595  INT4 idx, len;
2596 
2597  /* Sanity check input time series */
2605 
2606  /* Allocate polarization vectors and set to 0 */
2607  *hplus = XLALCreateREAL8TimeSeries( "H_PLUS", &V->epoch, 0.0,
2608  V->deltaT, &lalStrainUnit, V->data->length );
2609  *hcross = XLALCreateREAL8TimeSeries( "H_CROSS", &V->epoch, 0.0,
2610  V->deltaT, &lalStrainUnit, V->data->length );
2611  if ( ! hplus || ! hcross )
2613  memset((*hplus)->data->data, 0, (*hplus)->data->length
2614  * sizeof(*(*hplus)->data->data));
2615  memset((*hcross)->data->data, 0, (*hcross)->data->length
2616  * sizeof(*(*hcross)->data->data));
2617 
2618  mt = (m1 + m2)/LAL_MSUN_SI;
2619  eta = m1 * m2 / pow(m1 + m2, 2.0); // symmetric mass ratio - '\nu' in the paper
2620  dist = r / LAL_C_SI; // r (m) / c (m/s) --> dist in units of seconds
2621  /* convert mass from kg to s, so ampfac ~ M/dist is dimensionless */
2622  ampfac = mt * LAL_MTSUN_SI * eta / dist;
2623 
2624  /*
2625  * cosines and sines of inclination between
2626  * line of sight (N) and binary orbital angular momentum (L_N)
2627  */
2628  ci = cos(i); si = sin(i);
2629  ci2 = ci*ci;
2630  si2 = si*si;
2631 
2632  /* loop over time steps and compute first radial and angular orbital variables,
2633  * then the waveform polarizations h+ and hx */
2634  len = V->data->length;
2635  for(idx = 0; idx < len; idx++)
2636  {
2637  /* Abbreviated names in lower case for time series at this sample */
2638  phi = Phi->data->data[idx]; et = Ecc->data->data[idx]; u = U->data->data[idx]; v = V->data->data[idx];
2639 
2640  /* Some abbreviated functions in terms of u and et. */
2641  dt = 1. - et * cos(u);
2642  OTS = sqrt(1. - et * et);
2643 
2644  /*
2645  * First set the functions for the dimensionless orbital variables
2646  * (1/c)*dr/dt, (r/c)*dphi/dt, Z = G*m/(r*c^2) to 0.
2647  * Then use a switch to set proper non-zero values
2648  * up to order ph_O for the contributions to the dimensionless variables. Note we
2649  * fall through the PN orders and break only after Newt. order
2650  */
2651 
2652  rdot = rphidot = Z = 0;
2653 
2654  /* Common factors in PN accurate expressions for orbital variables */
2655  CF_rdot = et * v*sin(u)/dt;
2656  CF_rphidot = OTS * v / dt;
2657  CF_Z = pow(v, 2.0) / dt;
2658 
2659  switch( ph_O )
2660  {
2661  /* case LAL_PNORDER_FOUR: */
2662  case 8:
2663  XLALPrintError("XLAL Error - %s: dynamical variables not known "
2664  "to PN order %d\n", __func__, ph_O );
2666  break;
2667  /* case LAL_PNORDER_THREE_POINT_FIVE: */
2668  case 7:
2669  XLALPrintError("XLAL Error - %s: dynamical variables not known "
2670  "to PN order %d\n", __func__, ph_O );
2672  break;
2673  /* case LAL_PNORDER_THREE: */
2674  case 6:
2675  XLALPrintError("XLAL Error - %s: dynamical variables not yet implemented "
2676  "to PN order %d\n", __func__, ph_O );
2678  break;
2679  /* case LAL_PNORDER_TWO_POINT_FIVE: */
2680  case 5:
2681  XLALPrintError("XLAL Error - %s: dynamical variables not yet implemented "
2682  "to PN order %d\n", __func__, ph_O );
2684  break;
2685  case -1: // Highest known PN order - move if higher terms added!
2686  /* case LAL_PNORDER_TWO: */
2687  case 4:
2688  r_sc = 1.
2689  //==============================================================================
2690  + ((-24. + dt * (18. - 7. * eta) + 9. * eta + pow(et, 2.0) * (24. - 9. * eta
2691  + dt * (-6. + 7. * eta))) * pow(v, 2.0)) / (6. * dt * pow(OTS, 2.0))
2692  //==============================================================================
2693  + ((-288. + 765. * eta - 27. * pow(eta, 2.0)
2694  + pow(et, 4.0) * (261. * eta - 27 * pow(eta, 2.0))
2695  + pow(et, 2.0) * (288. - 1026. * eta + 54. * pow(eta, 2.0))
2696  + (-540. + pow(et, 2.0) * (540. - 216. * eta)
2697  + 216. * eta) * OTS + dt * (648. - 567. * eta + 35. * pow(eta, 2.0)
2698  + pow(et, 2.0) * (468. + 150. * eta - 70. * pow(eta, 2.0))
2699  + pow(et, 4.0) * (72. - 231. * eta + 35. * pow(eta, 2.0))
2700  + (180. - 72. * eta + pow(et, 2.0) * (-180. + 72. * eta)) * OTS)) * pow(v, 4.0))
2701  / (72. * dt * pow(OTS, 4.0));
2702  //==============================================================================
2703  phidot = 1.
2704  //===========================================================================================
2705  + (-1. + dt + pow(et, 2.0)) * (-4. + eta) * pow(v, 2.0) / (dt * pow(OTS, 2.0))
2706  //===========================================================================================
2707  + (-6. * pow(1. - pow(et, 2.0), 3.0) * eta * (3. + 2. * eta)
2708  + pow(dt, 3.0) * (42. + 22. * eta + 8.* pow(eta, 2.0)
2709  + pow(et, 2.0) * (-147. + 8. * eta - 14. * pow(eta, 2.0)))
2710  + dt * (108. + 63. * eta + 33. * pow(eta, 2.0)
2711  + pow(et, 2.0) * (-216. - 126. * eta - 66. * pow(eta, 2.0))
2712  + pow(et, 4.0) * (108. + 63. * eta + 33. * pow(eta, 2.0)))
2713  + pow(dt, 2.0) * (-240. - 31. * eta - 29. * pow(eta, 2.0)
2714  + pow(et, 4.0) * (-48. + 17. * eta - 17. * pow(eta, 2.0))
2715  + pow(et, 2.0) * (288. + 14. * eta + 46. * pow(eta,2)))
2716  + 18. * pow(dt, 2.0) * (-2. + dt + 2. * pow(et, 2.0)) * (-5. + 2. * eta) * OTS) * pow(v, 4.0)
2717  / (12. * pow(dt, 3.0) * pow(OTS, 4.0));
2718  //===========================================================================================
2719  rdot_sc = 1.
2720  //==========================================================================================
2721  + (-7. * eta + pow(et, 2.0) * (-6. + 7. * eta)) * pow(v, 2.0) / (6. * pow(OTS, 2.0))
2722  //==========================================================================================
2723  + (-135. * eta + 9. * pow(eta, 2.0) + pow(et, 2.0) * (405. * eta - 27. * pow(eta, 2.0))
2724  + pow(et, 6.0) * (135. * eta - 9. * pow(eta, 2.0))
2725  + pow(et, 4.0) * (-405. * eta + 27 * pow(eta, 2.0))
2726  + dt * (-540. + 351. * eta - 9. * pow(eta, 2.0)
2727  + pow(et, 4.0) * (-540. + 351. * eta - 9. * pow(eta, 2.0))
2728  + pow(et, 2.0) * (1080. - 702. * eta + 18. * pow(eta, 2.0)))
2729  + pow(dt, 3.0) * (-324. + 189. * eta + 35. * pow(eta, 2.0)
2730  + pow(et, 2.0) * (-234. + 366. * eta - 70. * pow(eta, 2.0))
2731  + pow(et, 4.0) * (72. - 231. * eta + 35. * pow(eta, 2.0)))
2732  - 36 * pow(dt, 2.0) * (3. + dt) * (1 - pow(et, 2.0)) * (-5. + 2. * eta) * OTS) * pow(v, 4.0)
2733  / (72. * pow(dt, 3.0) * pow(OTS, 4.0));
2734  //==========================================================================================
2735  break;
2736  /* case LAL_PNORDER_ONE_POINT_FIVE: */
2737  case 3:
2738  r_sc = 1.
2739  //===========================================================================
2740  + ((-24. + dt * (18. - 7. * eta) + 9. * eta + pow(et, 2.0) * (24. - 9. * eta
2741  + dt * (-6. + 7. * eta))) * pow(v, 2.0)) / (6. * dt * pow(OTS, 2.0));
2742  //===========================================================================
2743  phidot = 1.
2744  //==============================================================================
2745  + (-1. + dt + pow(et, 2.0)) * (-4. + eta) * pow(v, 2.0) / (dt * pow(OTS, 2.0));
2746  //==============================================================================
2747  rdot_sc = 1.
2748  //====================================================================================
2749  + (-7. * eta + pow(et, 2.0) * (-6. + 7. * eta)) * pow(v, 2.0) / (6. * pow(OTS, 2.0));
2750  //====================================================================================
2751  break;
2752  /* case LAL_PNORDER_ONE: */
2753  case 2:
2754  r_sc = 1.
2755  //===========================================================================
2756  + ((-24. + dt * (18. - 7. * eta) + 9. * eta + pow(et, 2.0) * (24. - 9. * eta
2757  + dt * (-6. + 7. * eta))) * pow(v, 2.0)) / (6. * dt * pow(OTS, 2.0));
2758  //===========================================================================
2759  phidot = 1.
2760  //==============================================================================
2761  + (-1. + dt + pow(et, 2.0)) * (-4. + eta) * pow(v, 2.0) / (dt * pow(OTS, 2.0));
2762  //==============================================================================
2763  rdot_sc = 1.
2764  //====================================================================================
2765  + (-7. * eta + pow(et, 2.0) * (-6. + 7. * eta)) * pow(v, 2.0) / (6. * pow(OTS, 2.0));
2766  //====================================================================================
2767  break;
2768  /*case LAL_PNORDER_HALF:*/
2769  case 1:
2770  r_sc = 1.;
2771  phidot = 1.;
2772  rdot_sc = 1.;
2773  break;
2774  /*case LAL_PNORDER_NEWTONIAN:*/
2775  case 0:
2776  r_sc = 1.;
2777  phidot = 1.;
2778  rdot_sc = 1.;
2779  break;
2780  default:
2781  XLALPrintError("XLAL Error - %s: Invalid phase PN order %d\n",
2782  __func__, ph_O );
2784  break;
2785  }
2786 
2787  /* Dimensionless rdot/c, (r/c)*phidot, Z = G*m/(r*c^2) entering the h+/x coefficients*/
2788  rdot = CF_rdot * rdot_sc;
2789  rphidot = CF_rphidot * r_sc * phidot;
2790  Z = CF_Z/r_sc;
2791 
2792  /*
2793  * First set all h+/x coefficients to 0. Then use a switch to
2794  * set proper non-zero values up to order ampO. Note we
2795  * fall through the PN orders and break only after Newt. order
2796  */
2797  hp0 = 0.;
2798  hc0 = 0.;
2799 
2800  switch( ampO )
2801  {
2802  /* case LAL_PNORDER_THREE_POINT_FIVE: */
2803  case 7:
2804  XLALPrintError("XLAL Error - %s: Amp. corrections not known "
2805  "to PN order %d\n", __func__, ampO );
2807  break;
2808  /* case LAL_PNORDER_THREE: */
2809  case 6:
2810  XLALPrintError("XLAL Error - %s: Amp. corrections not known "
2811  "to PN order %d\n", __func__, ampO );
2813  break;
2814  /* case LAL_PNORDER_TWO_POINT_FIVE: */
2815  case 5:
2816  XLALPrintError("XLAL Error - %s: Amp. corrections not known "
2817  "to PN order %d\n", __func__, ampO );
2819  break;
2820  /* case LAL_PNORDER_TWO: */
2821  case 4:
2822  XLALPrintError("XLAL Error - %s: Amp. corrections not known "
2823  "to PN order %d\n", __func__, ampO );
2825  break;
2826  /* case LAL_PNORDER_ONE_POINT_FIVE: */
2827  case 3:
2828  XLALPrintError("XLAL Error - %s: Amp. corrections not known "
2829  "to PN order %d\n", __func__, ampO );
2831  break;
2832  /* case LAL_PNORDER_ONE: */
2833  case 2:
2834  XLALPrintError("XLAL Error - %s: Amp. corrections not yet implemented "
2835  "to PN order %d\n", __func__, ampO );
2837  break;
2838  /*case LAL_PNORDER_HALF:*/
2839  case 1:
2840  XLALPrintError("XLAL Error - %s: Amp. corrections not yet implemented "
2841  "to PN order %d\n", __func__, ampO );
2843  break;
2844  case -1: // Highest known PN order - move if higher terms added!
2845  /*case LAL_PNORDER_NEWTONIAN:*/
2846  case 0:
2847  hp0 = - (si2 * (-pow(rphidot, 2.0) - pow(rdot, 2.0) + Z))
2848  - (1. + ci2) * ((pow(rphidot, 2.0) - pow(rdot, 2.0) + Z) * cos(2. * phi)
2849  + (2. * rphidot * rdot) * sin(2. * phi));
2850  hc0 = - 2. * ci * (-2. * rphidot * rdot * cos(2. * phi)
2851  + (pow(rphidot, 2.0) - pow(rdot, 2.0) + Z) * sin(2. * phi));
2852  break;
2853  default:
2854  XLALPrintError("XLAL Error - %s: Invalid amp. PN order %d\n",
2855  __func__, ampO );
2857  break;
2858  } /* End switch on ampO */
2859 
2860  /* Fill the output polarization arrays */
2861  (*hplus)->data->data[idx] = ampfac*hp0;
2862  (*hcross)->data->data[idx] = ampfac*hc0;
2863 
2864  } /* end loop over time series samples idx */
2865  return XLAL_SUCCESS;
2866 }
2867 
2868 /**
2869  * Computes polarizations h+ and hx for a spinning, precessing binary
2870  * when provided time series of all the dynamical quantities.
2871  * Amplitude can be chosen between 1.5PN and Newtonian orders (inclusive).
2872  *
2873  * Based on K.G. Arun, Alesssandra Buonanno, Guillaume Faye and Evan Ochsner
2874  * \"Higher-order spin effects in the amplitude and phase of gravitational
2875  * waveforms emitted by inspiraling compact binaries: Ready-to-use
2876  * gravitational waveforms\", Phys Rev. D 79, 104023 (2009), arXiv:0810.5336
2877  *
2878  * HOWEVER, the formulae have been adapted to use the output of the so-called
2879  * \"Frameless\" convention for evolving precessing binary dynamics,
2880  * which is not susceptible to hitting coordinate singularities.
2881  *
2882  * FIXME: Clean up and commit Mathematica NB Showing correctness. Cite here.
2883  *
2884  * NOTE: The vectors MUST be given in the so-called radiation frame where
2885  * Z is the direction of propagation, X is the principal '+' axis and Y = Z x X
2886  * For different convention (Z is the direction of initial total angular
2887  * momentum, useful for GRB and comparison to NR, see XLALSimSpinInspiralGenerator())
2888  */
2890  REAL8TimeSeries **hplus, /**< +-polarization waveform [returned] */
2891  REAL8TimeSeries **hcross, /**< x-polarization waveform [returned] */
2892  REAL8TimeSeries *V, /**< post-Newtonian parameter */
2893  REAL8TimeSeries *Phi, /**< orbital phase */
2894  REAL8TimeSeries *S1x, /**< Spin1 vector x component */
2895  REAL8TimeSeries *S1y, /**< Spin1 vector y component */
2896  REAL8TimeSeries *S1z, /**< Spin1 vector z component */
2897  REAL8TimeSeries *S2x, /**< Spin2 vector x component */
2898  REAL8TimeSeries *S2y, /**< Spin2 vector y component */
2899  REAL8TimeSeries *S2z, /**< Spin2 vector z component */
2900  REAL8TimeSeries *LNhatx, /**< unit orbital ang. mom. x comp. */
2901  REAL8TimeSeries *LNhaty, /**< unit orbital ang. mom. y comp. */
2902  REAL8TimeSeries *LNhatz, /**< unit orbital ang. mom. z comp. */
2903  REAL8TimeSeries *E1x, /**< orbital plane basis vector x comp. */
2904  REAL8TimeSeries *E1y, /**< orbital plane basis vector y comp. */
2905  REAL8TimeSeries *E1z, /**< orbital plane basis vector z comp. */
2906  REAL8 m1, /**< mass of companion 1 (kg) */
2907  REAL8 m2, /**< mass of companion 2 (kg) */
2908  REAL8 r, /**< distance of source (m) */
2909  INT4 ampO /**< twice amp. post-Newtonian order */
2910  )
2911 {
2912  REAL8 s1x, s1y, s1z, s2x, s2y, s2z, lnhx, lnhy, lnhz;
2913  REAL8 e1x, e1y, e1z, e2x, e2y, e2z, nx, ny, nz, lx, ly, lz;
2914  REAL8 nx2, ny2, nz2, nz3, lx2, ly2, lz2, lz3;
2915  REAL8 hplus0, hcross0, hplus05, hcross05, hplus1, hcross1;
2916  REAL8 hplus15, hcross15, hplusSpin1, hcrossSpin1;
2917  REAL8 hplusSpin15, hcrossSpin15, hplusTail15, hcrossTail15;
2918  REAL8 M, eta, dm, phi, v, v2, dist, ampfac;
2919  INT4 idx, len;
2920 
2921  /* Macros to check time series vectors */
2922  if ( !(hplus) || !(hcross) ) {
2923  XLALPrintError("** XLALSimInspiralPrecessingPolarizationWaveform error: **h+ and **hx are expected to be non NULL!\n");
2925  }
2953 
2954  /* Allocate polarization vectors and set to 0 */
2955  *hplus = XLALCreateREAL8TimeSeries( "H_PLUS", &V->epoch,
2956  0.0, V->deltaT, &lalStrainUnit, V->data->length );
2957  *hcross = XLALCreateREAL8TimeSeries( "H_CROSS", &V->epoch,
2958  0.0, V->deltaT, &lalStrainUnit, V->data->length );
2959  if ( ! hplus || ! hcross )
2961  memset((*hplus)->data->data, 0,
2962  (*hplus)->data->length*sizeof(*(*hplus)->data->data));
2963  memset((*hcross)->data->data, 0,
2964  (*hcross)->data->length*sizeof(*(*hcross)->data->data));
2965 
2966  M = m1 + m2;
2967  eta = m1 * m2 / M / M; // symmetric mass ratio - '\nu' in the paper
2968  dm = (m1 - m2) / M; // frac. mass difference - \delta m/m in the paper
2969  dist = r / LAL_C_SI; // r (m) / c (m/s) --> dist in units of seconds
2970  /* convert mass from kg to s, so ampfac ~ M/dist is dimensionless */
2971  ampfac = 2. * M * LAL_G_SI * pow(LAL_C_SI, -3) * eta / dist;
2972 
2973  /* loop over time steps and compute polarizations h+ and hx */
2974  len = V->data->length;
2975  for(idx = 0; idx < len; idx++)
2976  {
2977  /* Abbreviated names in lower case for time series at this sample */
2978  phi = Phi->data->data[idx]; v = V->data->data[idx]; v2 = v * v;
2979  lnhx = LNhatx->data->data[idx]; e1x = E1x->data->data[idx];
2980  lnhy = LNhaty->data->data[idx]; e1y = E1y->data->data[idx];
2981  lnhz = LNhatz->data->data[idx]; e1z = E1z->data->data[idx];
2982  s1x = S1x->data->data[idx]; s2x = S2x->data->data[idx];
2983  s1y = S1y->data->data[idx]; s2y = S2y->data->data[idx];
2984  s1z = S1z->data->data[idx]; s2z = S2z->data->data[idx];
2985 
2986  /* E2 = LNhat x E1 */
2987  e2x = lnhy*e1z - lnhz*e1y;
2988  e2y = lnhz*e1x - lnhx*e1z;
2989  e2z = lnhx*e1y - lnhy*e1x;
2990 
2991  /* Unit orbital separation vector */
2992  nx = e1x*cos(phi) + e2x*sin(phi);
2993  ny = e1y*cos(phi) + e2y*sin(phi);
2994  nz = e1z*cos(phi) + e2z*sin(phi);
2995 
2996  /* Unit inst. orbital velocity vector */
2997  lx = e2x*cos(phi) - e1x*sin(phi);
2998  ly = e2y*cos(phi) - e1y*sin(phi);
2999  lz = e2z*cos(phi) - e1z*sin(phi);
3000 
3001  /* Powers of vector components */
3002  nx2 = nx*nx; ny2 = ny*ny; nz2 = nz*nz; nz3 = nz*nz2;
3003  lx2 = lx*lx; ly2 = ly*ly; lz2 = lz*lz; lz3 = lz*lz2;
3004 
3005  /*
3006  * First set all h+/x coefficients to 0. Then use a switch to
3007  * set proper non-zero values up to order ampO. Note we
3008  * fall through the PN orders and break only after Newt. order
3009  */
3010  hplus0 = hplus05 = hplus1 = hplus15 = hplusTail15 = 0.;
3011  hcross0 = hcross05 = hcross1 = hcross15 = hcrossTail15 = 0.;
3012  hplusSpin1 = hplusSpin15 = hcrossSpin1 = hcrossSpin15 = 0.;
3013 
3014  switch( ampO )
3015  {
3016  /*
3017  * case LAL_PNORDER_THREE_POINT_FIVE:
3018  * case LAL_PNORDER_THREE:
3019  * case LAL_PNORDER_TWO_POINT_FIVE:
3020  * case LAL_PNORDER_TWO:
3021  */
3022  case 7:
3023  case 6:
3024  case 5:
3025  case 4:
3026  XLALPrintError("XLAL Error - %s: Amp. corrections not known "
3027  "to PN order %d, highest is %d\n", __func__, ampO,
3030  break;
3031  case -1: /* Use highest known PN order - move if new orders added */
3032  /*case LAL_PNORDER_ONE_POINT_FIVE:*/
3033  case 3:
3034  /* 1.5PN non-spinning amp. corrections */
3035  hplus15 = (dm*(2*lx*nx*nz*(-95 + 90*lz2 - 65*nz2
3036  - 2*eta*(-9 + 90*lz2 - 65*nz2)) - 2*ly*ny*nz
3037  * (-95 + 90*lz2 - 65*nz2 - 2*eta*(-9 + 90*lz2 - 65*nz2))
3038  + 6*lx2*lz*(13 - 4*lz2 + 29*nz2 + eta*(-2 + 8*lz2
3039  - 58*nz2)) - 6*ly2*lz*(13 - 4*lz2 + 29*nz2 + eta
3040  * (-2 + 8*lz2 - 58*nz2)) - lz*(nx2 - ny2)*(83 - 6*lz2
3041  + 111*nz2 + 6*eta*(-1 + 2*lz2 - 37*nz2))))/24.;
3042  hcross15 = (dm*(lz*(6*(19 - 4*eta)*lx*ly + (-101 + 12*eta)
3043  * nx*ny) + (-149 + 36*eta) * (ly*nx + lx*ny)*nz
3044  + 6*(-3 + eta) * (2*lx*ly*lz - lz*nx*ny - 3*ly*nx*nz
3045  - 3*lx*ny*nz) + (1 - 2*eta) * (6*lz3*(-4*lx*ly + nx*ny)
3046  + 90*lz2*(ly*nx + lx*ny)*nz + 3*lz*(58*lx*ly
3047  - 37*nx*ny)*nz2 - 65*(ly*nx + lx*ny)*nz3)))/12.;
3048  /* 1.5PN spinning amp. corrections */
3049  hplusSpin15 = (6*lz*ny*s1x + 6*dm*lz*ny*s1x - 3*eta*lz*ny*s1x
3050  + 2*ly2*lnhy*s1y + 2*dm*ly2*lnhy*s1y
3051  + 2*eta*ly2*lnhy*s1y + 6*lz*nx*s1y + 6*dm*lz*nx*s1y
3052  - 3*eta*lz*nx*s1y + 8*lnhy*nx2*s1y + 8*dm*lnhy*nx2*s1y
3053  - eta*lnhy*nx2*s1y - 8*lnhy*ny2*s1y - 8*dm*lnhy*ny2*s1y
3054  + eta*lnhy*ny2*s1y + 2*ly2*lnhz*s1z + 2*dm*ly2*lnhz*s1z
3055  + 2*eta*ly2*lnhz*s1z - 6*ly*nx*s1z - 6*dm*ly*nx*s1z
3056  - 9*eta*ly*nx*s1z + 8*lnhz*nx2*s1z + 8*dm*lnhz*nx2*s1z
3057  - eta*lnhz*nx2*s1z - 8*lnhz*ny2*s1z - 8*dm*lnhz*ny2*s1z
3058  + eta*lnhz*ny2*s1z + 6*lz*ny*s2x - 6*dm*lz*ny*s2x
3059  - 3*eta*lz*ny*s2x + lnhx*(2*ly2*((1 + dm + eta)*s1x
3060  + (1 - dm + eta)*s2x) + (nx2 - ny2)*((8 + 8*dm - eta)
3061  * s1x - (-8 + 8*dm + eta)*s2x)) + 2*ly2*lnhy*s2y
3062  - 2*dm*ly2*lnhy*s2y + 2*eta*ly2*lnhy*s2y + 6*lz*nx*s2y
3063  - 6*dm*lz*nx*s2y - 3*eta*lz*nx*s2y + 8*lnhy*nx2*s2y
3064  - 8*dm*lnhy*nx2*s2y - eta*lnhy*nx2*s2y - 8*lnhy*ny2*s2y
3065  + 8*dm*lnhy*ny2*s2y + eta*lnhy*ny2*s2y + 2*ly2*lnhz*s2z
3066  - 2*dm*ly2*lnhz*s2z + 2*eta*ly2*lnhz*s2z - 6*ly*nx*s2z
3067  + 6*dm*ly*nx*s2z - 9*eta*ly*nx*s2z + 8*lnhz*nx2*s2z
3068  - 8*dm*lnhz*nx2*s2z - eta*lnhz*nx2*s2z - 8*lnhz*ny2*s2z
3069  + 8*dm*lnhz*ny2*s2z + eta*lnhz*ny2*s2z - 3*lx*ny
3070  * ((2 + 2*dm + 3*eta)*s1z + (2 - 2*dm + 3*eta)*s2z)
3071  - 2*lx2*(lnhx*((1 + dm + eta)*s1x + (1 - dm + eta)*s2x)
3072  + lnhy*((1 + dm + eta)*s1y + (1 - dm + eta)*s2y)
3073  + lnhz*((1 + dm + eta)*s1z + (1 - dm + eta)*s2z)))/3.;
3074  hcrossSpin15 = (-3*lz*(nx*((2 + 2*dm - eta)*s1x
3075  - (-2 + 2*dm + eta)*s2x) + ny*((-2 - 2*dm + eta)*s1y
3076  + (-2 + 2*dm + eta)*s2y)) + ny*(-6*ly*s1z - 6*dm*ly*s1z
3077  - 9*eta*ly*s1z + 16*lnhz*nx*s1z + 16*dm*lnhz*nx*s1z
3078  - 2*eta*lnhz*nx*s1z + 2*lnhx*nx*((8 + 8*dm - eta)*s1x
3079  - (-8 + 8*dm + eta)*s2x) + 2*lnhy*nx*((8 + 8*dm - eta)
3080  * s1y - (-8 + 8*dm + eta)*s2y) - 6*ly*s2z + 6*dm*ly*s2z
3081  - 9*eta*ly*s2z + 16*lnhz*nx*s2z - 16*dm*lnhz*nx*s2z
3082  - 2*eta*lnhz*nx*s2z) - lx*(4*lnhx*ly*((1 + dm + eta)*s1x
3083  + (1 - dm + eta)*s2x) - 3*nx*((2 + 2*dm + 3*eta)*s1z
3084  + (2 - 2*dm + 3*eta)*s2z) + 4*ly*(lnhy*((1 + dm + eta)
3085  * s1y + (1 - dm + eta)*s2y) + lnhz*((1 + dm + eta)*s1z
3086  + (1 - dm + eta)*s2z))))/3.;
3087  /* 1.5PN tail amp. corrections */
3088  hplusTail15 = 2*((lx2 - ly2 - nx2 + ny2)*LAL_PI);
3089  hcrossTail15 = 4*((lx*ly - nx*ny)*LAL_PI);
3090 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3091  __attribute__ ((fallthrough));
3092 #endif
3093 
3094  /*case LAL_PNORDER_ONE:*/
3095  case 2:
3096  /* 1PN non-spinning amp. corrections */
3097  hplus1 = (-13*lx2 + 13*ly2 + 6*lx2*lz2 - 6*ly2*lz2
3098  + 13*(nx2 - ny2) - 2*lz2*(nx2 - ny2) - 32*lx*lz*nx*nz
3099  + 32*ly*lz*ny*nz - 14*lx2*nz2 + 14*ly2*nz2
3100  + 10*(nx2 - ny2)*nz2)/6. + (eta*(lx2 - 18*lx2*lz2
3101  + 96*lx*lz*nx*nz - 96*ly*lz*ny*nz + 42*lx2*nz2
3102  + ly2*(-1 + 18*lz2 - 42*nz2) + (nx2 - ny2)
3103  * (-1 + 6*lz2 - 30*nz2)))/6.;
3104  hcross1 = (eta*(lx*ly - nx*ny - 6*(lz2*(3*lx*ly - nx*ny)
3105  - 8*lz*(ly*nx + lx*ny)*nz + (-7*lx*ly
3106  + 5*nx*ny)*nz2)))/3. + (-13*(lx*ly - nx*ny)
3107  + 2*(lz2*(3*lx*ly - nx*ny) - 8*lz*(ly*nx + lx*ny)*nz
3108  + (-7*lx*ly + 5*nx*ny)*nz2))/3.;
3109  /* 1PN spinning amp. corrections */
3110  hplusSpin1 = (-(ny*((1 + dm)*s1x + (-1 + dm)*s2x))
3111  - nx*((1 + dm)*s1y + (-1 + dm)*s2y))/2.;
3112  hcrossSpin1 = (nx*((1 + dm)*s1x + (-1 + dm)*s2x)
3113  - ny*((1 + dm)*s1y + (-1 + dm)*s2y))/2.;
3114 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3115  __attribute__ ((fallthrough));
3116 #endif
3117 
3118  /*case LAL_PNORDER_HALF:*/
3119  case 1:
3120  /* 0.5PN non-spinning amp. corrections */
3121  hplus05 = (dm*(-2*lx2*lz + 2*ly2*lz + lz*(nx2 - ny2)
3122  + 6*lx*nx*nz - 6*ly*ny*nz))/2.;
3123  hcross05 = dm*(-2*lx*ly*lz + lz*nx*ny
3124  + 3*ly*nx*nz + 3*lx*ny*nz);
3125 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3126  __attribute__ ((fallthrough));
3127 #endif
3128  /*case LAL_PNORDER_NEWTONIAN:*/
3129  case 0:
3130  /* Newtonian order polarizations */
3131  hplus0 = lx2 - ly2 - nx2 + ny2;
3132  hcross0 = 2*lx*ly - 2*nx*ny;
3133 
3134  break;
3135  default:
3136  XLALPrintError("XLAL Error - %s: Invalid amp. PN order %d\n",
3137  __func__, ampO );
3139  break;
3140  } /* End switch on ampO */
3141 
3142  /* Fill the output polarization arrays */
3143  (*hplus)->data->data[idx] = ampfac * v2 * ( hplus0
3144  + v * ( hplus05 + v * ( hplus1 + hplusSpin1
3145  + v * ( hplus15 + hplusSpin15 + hplusTail15 ) ) ) );
3146  (*hcross)->data->data[idx] = ampfac * v2 * ( hcross0
3147  + v * ( hcross05 + v * ( hcross1 + hcrossSpin1
3148  + v * ( hcross15 + hcrossSpin15 + hcrossTail15 ) ) ) );
3149  } /* end of loop over time samples, idx */
3150  return XLAL_SUCCESS;
3151 }
3152 
3153 /**
3154  * Computes polarizations h+ and hx for a spinning, precessing binary
3155  * when provided a single value of all the dynamical quantities.
3156  * Amplitude can be chosen between 1.5PN and Newtonian orders (inclusive).
3157  *
3158  * Based on K.G. Arun, Alesssandra Buonanno, Guillaume Faye and Evan Ochsner
3159  * \"Higher-order spin effects in the amplitude and phase of gravitational
3160  * waveforms emitted by inspiraling compact binaries: Ready-to-use
3161  * gravitational waveforms\", Phys Rev. D 79, 104023 (2009), arXiv:0810.5336
3162  *
3163  * HOWEVER, the formulae have been adapted to use the output of the so-called
3164  * \"Frameless\" convention for evolving precessing binary dynamics,
3165  * which is not susceptible to hitting coordinate singularities.
3166  *
3167  * This has been written to reproduce XLALSimInspiralPrecessingPolarizationWaveforms.
3168  * If hplus and hcross are the output of XLALSimInspiralPrecessingPolarizationWaveforms,
3169  * and hp(n) and hc(n) the output of this function for a given harmonic number, then
3170  *
3171  * hplus = sum_{n=0}^5 hp(n)*exp(-i*n*Phi) + c.c.
3172  * hcross = sum_{n=0}^5 hc(n)*exp(-i*n*Phi) + c.c.
3173  *
3174  * NOTE: The vectors MUST be given in the so-called radiation frame where
3175  * Z is the direction of propagation, X is the principal '+' axis and Y = Z x X
3176  * For different convention (Z is the direction of initial total angular
3177  * momentum, useful for GRB and comparison to NR, see XLALSimSpinInspiralGenerator())
3178  * FIXME take out v0 as it can be absorbed in a 4PN additional phase term
3179  * see discussion in sec. VIII of Class.Quant.Grav. 25 (2008) 165003,
3180  * arXiv 0802.1249.
3181  */
3183  COMPLEX16 *hplus, /**< +-polarization waveform [returned] */
3184  COMPLEX16 *hcross, /**< x-polarization waveform [returned] */
3185  REAL8 v, /**< post-Newtonian parameter */
3186  REAL8 s1x, /**< Spin1 vector x component */
3187  REAL8 s1y, /**< Spin1 vector y component */
3188  REAL8 s1z, /**< Spin1 vector z component */
3189  REAL8 s2x, /**< Spin2 vector x component */
3190  REAL8 s2y, /**< Spin2 vector y component */
3191  REAL8 s2z, /**< Spin2 vector z component */
3192  REAL8 lnhx, /**< unit orbital ang. mom. x comp. */
3193  REAL8 lnhy, /**< unit orbital ang. mom. y comp. */
3194  REAL8 lnhz, /**< unit orbital ang. mom. z comp. */
3195  REAL8 e1x, /**< orbital plane basis vector x comp. */
3196  REAL8 e1y, /**< orbital plane basis vector y comp. */
3197  REAL8 e1z, /**< orbital plane basis vector z comp. */
3198  REAL8 dm, /**< dimensionless mass difference (m1 - m2)/(m1 + m2) > 0 */
3199  REAL8 eta, /**< symmetric mass ratio m1*m2/(m1 + m2)^2 */
3200  REAL8 v0, /**< tail-term gauge choice (default = 1) */
3201  INT4 n, /**< harmonic number */
3202  INT4 ampO /**< twice amp. post-Newtonian order */
3203  )
3204 {
3205  /* E2 = LNhat x E1 */
3206  REAL8 e2x = lnhy*e1z - lnhz*e1y;
3207  REAL8 e2y = lnhz*e1x - lnhx*e1z;
3208  REAL8 e2z = lnhx*e1y - lnhy*e1x;
3209 
3210  REAL8 v2 = v*v;
3211  REAL8 v3 = v2*v;
3212  REAL8 v4 = v3*v;
3213  REAL8 v5 = v4*v;
3214 
3215  REAL8 twom1 = (1. + dm);
3216  REAL8 twom2 = (1. - dm);
3217 
3218  REAL8 a1x = s1x*twom1;
3219  REAL8 a1y = s1y*twom1;
3220  REAL8 a1z = s1z*twom1;
3221  REAL8 a2x = s2x*twom2;
3222  REAL8 a2y = s2y*twom2;
3223  REAL8 a2z = s2z*twom2;
3224 
3225  REAL8 logfac;
3226 
3227  /*
3228  * First set all h+/x coefficients to 0. Then use a switch to
3229  * set proper non-zero values up to order ampO. Note we
3230  * fall through the PN orders and break only after Newt. order
3231  */
3232  *hplus = 0.;
3233  *hcross = 0.;
3234 
3235  REAL8 fact1, fact2, fact3, fact4, fact5, fact6, fact7, fact8, fact9;
3236 
3237  REAL8 e1xe1x = e1x*e1x;
3238  REAL8 e1xe1y = e1x*e1y;
3239  REAL8 e1xe1z = e1x*e1z;
3240  REAL8 e1ye1y = e1y*e1y;
3241  REAL8 e1ye1z = e1y*e1z;
3242  REAL8 e1ze1z = e1z*e1z;
3243 
3244  REAL8 e2xe2x = e2x*e2x;
3245  REAL8 e2xe2y = e2x*e2y;
3246  REAL8 e2xe2z = e2x*e2z;
3247  REAL8 e2ye2y = e2y*e2y;
3248  REAL8 e2ye2z = e2y*e2z;
3249  REAL8 e2ze2z = e2z*e2z;
3250 
3251  REAL8 e1xe2x = e1x*e2x;
3252  REAL8 e1xe2y = e1x*e2y;
3253  REAL8 e1ye2x = e1y*e2x;
3254  REAL8 e1xe2z = e1x*e2z;
3255  REAL8 e1ze2x = e1z*e2x;
3256  REAL8 e1ye2y = e1y*e2y;
3257  REAL8 e1ye2z = e1y*e2z;
3258  REAL8 e1ze2y = e1z*e2y;
3259  REAL8 e1ze2z = e1z*e2z;
3260 
3261  switch(n) // harmonic number
3262  {
3263  case 0:
3264  switch( ampO )
3265  {
3266  case -1: /* Use highest known PN order - move if new orders added */
3267  case 3:
3268  case 2:
3269  case 1:
3270  fact1 = v3*0.125;
3271  fact2 = 7. + dm;
3272  fact3 = 7. - dm;
3273  fact4 = a1x*fact2 + a2x*fact3;
3274  fact5 = a1y*fact2 + a2y*fact3;
3275  fact6 = lnhx*fact4;
3276  fact7 = lnhy*fact5;
3277  fact8 = lnhz*(a1z*fact2 + a2z*fact3);
3278  fact9 = fact6 + fact7 + fact8;
3279 
3280  *hplus += fact1*(fact4*lnhx - fact5*lnhy + fact9*(e1xe1x - e1ye1y
3281  + e2xe2x - e2ye2y));
3282  *hcross += fact1*(fact4*lnhy - fact5*lnhx + fact9*(e1xe1y + e2xe2y));
3283  case 0:
3284  break;
3285  default:
3286  XLALPrintError("XLAL Error - %s: Invalid amp. PN order %d, highest is %d\n", __func__, ampO, 3 );
3287  break;
3288  }
3289  break;
3290 
3291  case 1: // harmonic number
3292  switch( ampO )
3293  {
3294  case -1: /* Use highest known PN order - move if new orders added */
3295  case 3:
3296  fact1 = 1. - 2.*eta;
3297  fact2 = 8. + fact1*(30. + 9.*e1ze1z + 19.*e2ze2z);
3298  fact3 = 72. + fact1*(6. + e2ze2z - 9.*e1ze1z);
3299  fact4 = 40. + fact1*(18. + 15.*e2ze2z + 5.*e1ze1z);
3300  fact5 = 8. + fact1*(30. + 9.*e2ze2z + 19.*e1ze1z);
3301  fact6 = 72. + fact1*(6. + e1ze1z - 9.*e2ze2z);
3302  fact7 = 40. + fact1*(18. + 15.*e1ze1z + 5.*e2ze2z);
3303  fact8 = v5*dm/384.;
3304 
3305  *hplus += fact8*(((e1xe1x - e1ye1y)*e2z*fact2 - (e2xe2x
3306  - e2ye2y)*e2z*fact3 + 2.*e1z*(e1ye2y - e1xe2x)*fact4) + I*((-(e2xe2x
3307  - e2ye2y)*fact5 + (e1xe1x - e1ye1y)*fact6)*e1z - 2.*e2z*(e1ye2y
3308  - e1xe2x)*fact7));
3309  *hcross += (2.*fact8)*((-e2xe2y*e2z*fact3 + e1xe2z*e1y*fact2
3310  - e1z*(e1xe2y + e1ye2x)*fact4) + I*((e1xe2y + e1ye2x)*e2z*fact7
3311  + (e1xe1y*fact6 - e2xe2y*fact5)*e1z));
3312 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3313  __attribute__ ((fallthrough));
3314 #endif
3315  case 2:
3316  fact1 = v4*0.25;
3317 
3318  *hplus += fact1*(((a2y - a1y)*e1x - (a1x - a2x)*e1y) + I*((a2y
3319  - a1y)*e2x - (a1x - a2x)*e2y));
3320  *hcross += fact1*(((a1x - a2x)*e1x - (a1y - a2y)*e1y) + I*((a1x
3321  - a2x)*e2x - (a1y - a2y)*e2y));
3322 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3323  __attribute__ ((fallthrough));
3324 #endif
3325  case 1:
3326  fact1 = e1xe2x - e1ye2y;
3327  fact2 = e1ye1y - e1xe1x;
3328  fact3 = e2xe2x - e2ye2y;
3329  fact4 = e1xe2y + e1ye2x;
3330  fact5 = e1xe1y;
3331  fact6 = e2xe2y;
3332  fact7 = dm*v3*0.0625;
3333 
3334  *hplus += fact7*((6.*e1z*fact1 + e2z*(5.*fact2 + fact3))
3335  + I*(e1z*(fact2 + 5.*fact3) - 6.*e2z*fact1));
3336  *hcross += (2.*fact7)*((3.*e1z*fact4 + e2z*(-5.*fact5 + fact6))
3337  + I*(e1z*(5.*fact6 - fact5) - 3.*e2z*fact4));
3338 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3339  __attribute__ ((fallthrough));
3340 #endif
3341  case 0:
3342  break;
3343  default:
3344  XLALPrintError("XLAL Error - %s: Invalid amp. PN order %d, highest is %d\n", __func__, ampO, 3 );
3345  break;
3346  }
3347  break;
3348 
3349  case 2: // harmonic number
3350  switch( ampO )
3351  {
3352  case -1: /* Use highest known PN order - move if new orders added */
3353  case 3:
3354  logfac = log(v/v0);
3355  fact1 = e1xe2x - e1ye2y;
3356  fact2 = -e1xe1x + e1ye1y + e2xe2x - e2ye2y;
3357  fact3 = e1ye2x + e1xe2y;
3358  fact4 = -e1xe1y + e2xe2y;
3359 
3360  *hplus += v5*((12.*fact1*logfac + fact2*LAL_PI) + I*(6.*fact2*logfac
3361  - 2.*fact1*LAL_PI));
3362  *hcross += v5*((2.*(6.*fact3*logfac + fact4*LAL_PI))
3363  + I*(2.*(6.*fact4*logfac - fact3*LAL_PI)));
3364 
3365  fact1 = a1x*(7. + dm) + a2x*(7. - dm);
3366  fact2 = a1y*(7. + dm) + a2y*(7. - dm);
3367  fact3 = a1z*(11. - 3.*dm) + a2z*(11. + 3.*dm);
3368  fact4 = a1x*(41. - dm) + a2x*(41. + dm);
3369  fact5 = a1y*(41. - dm) + a2y*(41. + dm);
3370  fact6 = a1z*(41. - dm) + a2z*(41. + dm);
3371  fact7 = lnhx*fact4 + lnhy*fact5 + lnhz*fact6;
3372  fact8 = e1xe1x - e1ye1y - (e2xe2x - e2ye2y);
3373  fact9 = v5/48.;
3374 
3375  *hplus += fact9*((3.*(e1ye2z + e1ze2y)*fact1 + 3.*(e1xe2z
3376  + e1ze2x)*fact2 - 6.*(e1ye2x + e1xe2y)*fact3 + fact8*fact7)
3377  + I*(-3.*(e1ye1z - e2ye2z)*fact1 - 3.*(e1xe1z - e2xe2z)*fact2
3378  + 6.*(e1xe1y - e2xe2y)*fact3 + 2.*(e1xe2x - e1ye2y)*fact7));
3379  *hcross += fact9*((-3.*(e1ze2x + e1xe2z)*fact1 + 3.*(e1ze2y
3380  + e1ye2z)*fact2 + 6.*(e1xe2x - e1ye2y)*fact3 + 2.*(e1xe1y
3381  - e2xe2y)*fact7) + I*(3.*(e1xe1z - e2xe2z)*fact1 - 3.*(e1ye1z
3382  - e2ye2z)*fact2 - 3.*fact8*fact3 + 2.*(e1ye2x + e1xe2y)*fact7));
3383 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3384  __attribute__ ((fallthrough));
3385 #endif
3386 
3387  case 2:
3388  fact5 = -1. + 3.*eta;
3389  fact1 = -13. + eta + (6.*e2ze2z + 2.*e1ze1z)*fact5;
3390  fact2 = -13. + eta + (6.*e1ze1z + 2.*e2ze2z)*fact5;
3391  fact3 = e1ze2z*fact5;
3392  fact4 = -13. + eta + 4.*(e1ze1z + e2ze2z)*fact5;
3393  fact6 = v4/6.;
3394 
3395  *hplus += fact6*((((e1ye1y - e1xe1x)*fact1 + (e2xe2x
3396  - e2ye2y)*fact2)*0.5) + I*(2.*(e1xe1x - e1ye1y + e2xe2x
3397  - e2ye2y)*fact3 + (e1ye2y - e1xe2x)*fact4));
3398  *hcross += fact6*((-e1xe1y*fact1 + e2xe2y*fact2) + I*(4.*(e1xe1y
3399  + e2xe2y)*fact3 - (e1ye2x + e1xe2y)*fact4));
3400 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3401  __attribute__ ((fallthrough));
3402 #endif
3403  case 1:
3404  case 0:
3405  *hplus += v2*(0.5*(e1ye1y - e2ye2y + e2xe2x - e1xe1x) + I*(e1ye2y
3406  - e1xe2x));
3407  *hcross += v2*((e2xe2y - e1xe1y) - I*(e1ye2x + e1xe2y));
3408  break;
3409  default:
3410  XLALPrintError("XLAL Error - %s: Invalid amp. PN order %d, highest is %d\n", __func__, ampO, 3 );
3411  break;
3412  }
3413  break;
3414 
3415  case 3: // harmonic number
3416  switch( ampO )
3417  {
3418  case -1: /* Use highest known PN order - move if new orders added */
3419  case 3:
3420  fact1 = v5*dm*9./256.;
3421  fact2 = 1. - 2.*eta;
3422  fact3 = 48. + fact2*(4. + 33.*e1ze1z + 9.*e2ze2z);
3423  fact4 = 48. + fact2*(4. + 15.*e1ze1z + 15.*e2ze2z);
3424  fact5 = 48. + fact2*(4. - 3.*e1ze1z + 21.*e2ze2z);
3425  fact6 = 48. + fact2*(4. + 33.*e2ze2z + 9.*e1ze1z);
3426  fact7 = 48. + fact2*(4. - 3.*e2ze2z + 21.*e1ze1z);
3427 
3428  *hplus += fact1*(((e2xe2x - e2ye2y)*e2z*fact3 + 2.*e1z*(e1ye2y
3429  - e1xe2x)*fact4 - (e1xe1x - e1ye1y)*e2z*fact5) + I*(2.*(e1ye2y
3430  - e1xe2x)*e2z*fact4 + (e1xe1x - e1ye1y)*e1z*fact6 - e1z*(e2xe2x
3431  - e2ye2y)*fact7));
3432  *hcross += fact1*((2.*(e2xe2y*e2z*fact3 - (e1xe2y + e1ye2x)*e1z*fact4
3433  - e1xe1y*e2z*fact5)) + I*(2.*(-e1z*e2xe2y*fact7 + e1xe1y*e1z*fact6
3434  - (e1xe2y + e1ye2x)*e2z*fact4)));
3435 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3436  __attribute__ ((fallthrough));
3437 #endif
3438  case 2:
3439  case 1:
3440  fact1 = v3*dm*9./16.;
3441  fact2 = 2.*(e1xe2x - e1ye2y);
3442  fact3 = e1xe1x - e1ye1y - (e2xe2x - e2ye2y);
3443  fact4 = 2.*(e1xe2y + e1ye2x);
3444  fact5 = 2.*(e1xe1y - e2xe2y);
3445 
3446  *hplus += fact1*((e1z*fact2 + e2z*fact3) - I*(e1z*fact3 - e2z*fact2));
3447  *hcross += fact1*((e1z*fact4 + e2z*fact5) + I*(-e1z*fact5
3448  + e2z*fact4));
3449 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3450  __attribute__ ((fallthrough));
3451 #endif
3452  case 0:
3453  break;
3454  default:
3455  XLALPrintError("XLAL Error - %s: Invalid amp. PN order %d, highest is %d\n", __func__, ampO, 3 );
3456  break;
3457  }
3458  break;
3459 
3460  case 4: // harmonic number
3461  switch( ampO )
3462  {
3463  case -1: /* Use highest known PN order - move if new orders added */
3464  case 3:
3465  case 2:
3466  fact1 = v4*4.*(1. - 3.*eta)/3.;
3467  fact2 = e1xe2x - e1ye2y;
3468  fact3 = e1xe1x - e1ye1y - (e2xe2x - e2ye2y);
3469  fact4 = e1ze1z - e2ze2z;
3470  fact5 = e1xe1y - e2xe2y;
3471  fact6 = e1ye2x + e1xe2y;
3472 
3473  *hplus = fact1*((0.5*fact4*fact3 - 2.*e1ze2z*fact2) + I*(fact4*fact2
3474  + e1ze2z*fact3));
3475  *hcross = fact1*((fact4*fact5 - 2.*e1ze2z*fact6) + I*(fact4*fact6
3476  + 2.*e1ze2z*fact5));
3477 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3478  __attribute__ ((fallthrough));
3479 #endif
3480  case 1:
3481  case 0:
3482  break;
3483  default:
3484  XLALPrintError("XLAL Error - %s: Invalid amp. PN order %d, highest is %d\n", __func__, ampO, 3 );
3485  break;
3486  }
3487  break;
3488 
3489  case 5: // harmonic number
3490  switch( ampO )
3491  {
3492  case -1: /* Use highest known PN order - move if new orders added */
3493  case 3:
3494  fact1 = -v5*dm*(1. - 2.*eta)*625./384.;
3495  fact2 = e1xe2x - e1ye2y;
3496  fact3 = e1xe1x - e1ye1y - (e2xe2x - e2ye2y);
3497  fact4 = e1z*(e1ze1z - 3.*e2ze2z);
3498  fact5 = e2z*(e2ze2z - 3.*e1ze1z);
3499  fact6 = e1ye2x + e1xe2y;
3500  fact7 = e1xe1y - e2xe2y;
3501 
3502  *hplus += (fact1)*((fact4*fact2 - 0.5*fact5*fact3) - I*(fact5*fact2
3503  + 0.5*fact4*fact3));
3504  *hcross += (fact1)*((fact4*fact6 - fact5*fact7) - I*(fact4*fact7
3505  + fact5*fact6));
3506 #if __GNUC__ >= 7 && !defined __INTEL_COMPILER
3507  __attribute__ ((fallthrough));
3508 #endif
3509  case 2:
3510  case 1:
3511  case 0:
3512  break;
3513  default:
3514  XLALPrintError("XLAL Error - %s: Invalid amp. PN order %d, highest is %d\n", __func__, ampO, 3 );
3515  break;
3516  }
3517  break;
3518 
3519  default: // harmonic number. zero at this order
3520  break;
3521  }
3522  return XLAL_SUCCESS;
3523 }
3524 
3525 /** @} */
3526 
3527 /**
3528  * @defgroup lalsimulation_inference LALSimulation-LALInference parameter transformations
3529  * @author Riccardo Sturani
3530  *
3531  * @brief Functions to transform waveform parameters between LALSimulation and LALInference coordinate conventions
3532  */
3533 
3534 /**
3535  * @ingroup lalsimulation_inference
3536  * @brief Transform Precessing Parameters
3537  *
3538  * @details Routine for transforming LALInference geometric variables to ChooseWaveform input
3539  *
3540  * Function to specify the desired orientation of a precessing binary in terms
3541  * of several angles and then compute the vector components with respect to
3542  * orbital angular momentum as needed to specify binary configuration for
3543  * ChooseTDWaveform.
3544  *
3545  * @image html lalsiminspiral_orbitelementsJ.svg Representation of input variables.
3546  *
3547  * ### Input:
3548  * * thetaJN is the inclination between total angular momentum (J) and the
3549  * direction of propagation (N=(0,sin(thetaJN),cos(thetaJN)))
3550  * @note This choice has been made to made so that thetaJN -> inclination
3551  * for \f$ S_{1}+S_{2} \to 0\f$.
3552  * * theta1 and theta2 are the inclinations of \f$S_{1,2}\f$
3553  * measured from the Newtonian orbital angular momentum (\f$L_{N}\f$).
3554  * * phi12 is the difference in azimuthal angles of \f$S_{1,2}\f$.
3555  * * chi1, chi2 are the dimensionless spin magnitudes ( chi1, chi2 \f$\le 1\f$)
3556  * * phiJL is the azimuthal angle of \f$L_{N}\f$ on its cone about J.
3557  * * m1, m2, f_ref, phiref are the component masses and reference GW frequency
3558  and orbital phase, they are needed to compute the magnitude of
3559  \f$L_{N}\f$, and thus J.
3560  *
3561  * ### Output:
3562  * incl - inclination angle of N relative to L_N (N=(0,sin(incl),cos(incl)))
3563  * in the p-q-Z frame.
3564  * x, y, z components \f$S_{1,2}\f$ (unit spin vectors times their
3565  * dimensionless spin magnitudes - i.e. they have unit magnitude for
3566  * extremal BHs and smaller magnitude for slower spins).
3567  * where x-y are rotated by phiRef with respect to p-q,
3568  * i.e. is \f$S_{1}\f$ wrt to x-y is (a,b,0), wrt to p-q will be
3569  * (a cos(phiRef) + b sin (phiRef), )
3570  * @note Here the \"total\" angular momentum is computed as
3571  * J = \f$L_{N}(1+l_{1PN}) + S_{1} + S_{2}\f$
3572  * where \f$L_N\f$ is the Newtonian orbital angular momentum and \f$l_{1PN}\f$
3573  * its relative 1PN corrections. In fact, there are
3574  * PN corrections to L which contribute to J that are NOT ACCOUNTED FOR
3575  * in this function. This is done so to avoid complications with spin-orbit
3576  * contributions to L, which would require the full knowledge fo the orbital
3577  * motion, not just the evolution of L (see e.g. eq.2.9c of
3578  * arXiv:gr-qc/9506022). Also, it is believed that the difference in Jhat
3579  * with or without these PN corrections to L is quite small.
3580  *
3581  * @attention fRef = 0 is not a valid choice. If you will pass fRef=0 into
3582  * ChooseWaveform, then here pass in f_min, the starting GW frequency
3583  *
3584  * UNREVIEWED
3585  */
3586 
3588  REAL8 *incl, /**< Inclination angle of L_N (returned) */
3589  REAL8 *S1x, /**< S1 x component (returned) */
3590  REAL8 *S1y, /**< S1 y component (returned) */
3591  REAL8 *S1z, /**< S1 z component (returned) */
3592  REAL8 *S2x, /**< S2 x component (returned) */
3593  REAL8 *S2y, /**< S2 y component (returned) */
3594  REAL8 *S2z, /**< S2 z component (returned) */
3595  const REAL8 thetaJN, /**< zenith angle between J and N (rad) */
3596  const REAL8 phiJL, /**< azimuthal angle of L_N on its cone about J (rad) */
3597  const REAL8 theta1, /**< zenith angle between S1 and LNhat (rad) */
3598  const REAL8 theta2, /**< zenith angle between S2 and LNhat (rad) */
3599  const REAL8 phi12, /**< difference in azimuthal angle btwn S1, S2 (rad) */
3600  const REAL8 chi1, /**< dimensionless spin of body 1 */
3601  const REAL8 chi2, /**< dimensionless spin of body 2 */
3602  const REAL8 m1_SI, /**< mass of body 1 (kg) */
3603  const REAL8 m2_SI, /**< mass of body 2 (kg) */
3604  const REAL8 fRef, /**< reference GW frequency (Hz) */
3605  const REAL8 phiRef /**< reference orbital phase */
3606  )
3607 {
3608  /* Check that fRef is sane */
3609  if( fRef == 0. )
3610  {
3611  XLALPrintError("XLAL Error - %s: fRef=0 is invalid. Please pass in the starting GW frequency instead.\n", __func__);
3613  }
3614  if( (chi1<0.) || (chi1>1.) || (chi2<0.) || (chi2>1.) )
3615  {
3616  XLALPrintError("XLAL Error - %s: chi1,2=0 must be between 0 and 1, values %8.4f -- %8.4f passed.\n", __func__,chi1,chi2);
3618  }
3619 
3620  REAL8 m1, m2, eta, v0, theta0, phi0, Jnorm, tmp1, tmp2;
3621  REAL8 Jhatx, Jhaty, Jhatz, LNhx, LNhy, LNhz, Jx, Jy, Jz, Lmag;
3622  REAL8 s1hatx,s1haty,s1hatz,s2hatx,s2haty,s2hatz;
3623  REAL8 s1x, s1y, s1z, s2x, s2y, s2z;
3624 
3625  /* Starting frame: LNhat is along the z-axis and the unit
3626  * spin vectors are defined from the angles relative to LNhat.
3627  * Note that we put s1hat in the x-z plane, and phi12
3628  * sets the azimuthal angle of s2hat measured from the x-axis.
3629  */
3630  LNhx = 0.;
3631  LNhy = 0.;
3632  LNhz = 1.;
3633  /* Spins are given wrt to L,
3634  * but still we cannot fill the spin as we do not know
3635  * what will be the relative orientation of L and N.
3636  * Note that these spin components are NOT wrt to binary
3637  * separation vector, but wrt to binary separation vector
3638  * at phiref=0.
3639  */
3640  s1hatx = sin(theta1)*cos(phiRef);
3641  s1haty = sin(theta1)*sin(phiRef);
3642  s1hatz = cos(theta1);
3643  s2hatx = sin(theta2) * cos(phi12+phiRef);
3644  s2haty = sin(theta2) * sin(phi12+phiRef);
3645  s2hatz = cos(theta2);
3646 
3647  /* Define several internal variables needed for magnitudes */
3648  m1 = m1_SI/LAL_MSUN_SI;
3649  m2 = m2_SI/LAL_MSUN_SI;
3650  eta=m1*m2/(m1+m2)/(m1+m2);
3651  // v parameter at reference point
3652  v0 = cbrt( (m1+m2) * LAL_MTSUN_SI *LAL_PI * fRef );
3653 
3654  /* Define S1, S2, J with proper magnitudes */
3655  Lmag = XLALSimInspiralLN(m1+m2,eta,v0)*(1.+v0*v0*XLALSimInspiralL_2PN(eta));
3656  s1x = m1 * m1 * chi1 * s1hatx;
3657  s1y = m1 * m1 * chi1 * s1haty;
3658  s1z = m1 * m1 * chi1 * s1hatz;
3659  s2x = m2 * m2 * chi2 * s2hatx;
3660  s2y = m2 * m2 * chi2 * s2haty;
3661  s2z = m2 * m2 * chi2 * s2hatz;
3662  Jx = s1x + s2x;
3663  Jy = s1y + s2y;
3664  Jz = Lmag + s1z + s2z;
3665 
3666  /* Normalize J to Jhat, find its angles in starting frame */
3667  Jnorm = sqrt( Jx*Jx + Jy*Jy + Jz*Jz);
3668  Jhatx = Jx / Jnorm;
3669  Jhaty = Jy / Jnorm;
3670  Jhatz = Jz / Jnorm;
3671  theta0 = acos(Jhatz);
3672  phi0 = atan2(Jhaty, Jhatx);
3673 
3674  /* Rotation 1: Rotate about z-axis by -phi0 to put Jhat in x-z plane */
3675  ROTATEZ(-phi0, s1hatx, s1haty, s1hatz);
3676  ROTATEZ(-phi0, s2hatx, s2haty, s2hatz);
3677  //do not need to perform explicitly the rotation on L and J
3678  //ROTATEZ(-phi0, Jhatx, Jhaty, Jhatz);
3679  //ROTATEZ(-phi0, LNhx, LNhy, LNhz);
3680 
3681  /* Rotation 2: Rotate about new y-axis by -theta0
3682  * to put Jhat along z-axis
3683  */
3684  ROTATEY(-theta0, LNhx, LNhy, LNhz);
3685  ROTATEY(-theta0, s1hatx, s1haty, s1hatz);
3686  ROTATEY(-theta0, s2hatx, s2haty, s2hatz);
3687  //do not need to perform explicitly the rotation on J
3688  //ROTATEY(-theta0, Jhatx, Jhaty, Jhatz);
3689 
3690  /* Rotation 3: Rotate about new z-axis by phiJL to put L at desired
3691  * azimuth about J. Note that is currently in x-z plane towards -x
3692  * (i.e. azimuth=pi). Hence we rotate about z by phiJL - LAL_PI
3693  */
3694  ROTATEZ(phiJL - LAL_PI, LNhx, LNhy, LNhz);
3695  ROTATEZ(phiJL - LAL_PI, s1hatx, s1haty, s1hatz);
3696  ROTATEZ(phiJL - LAL_PI, s2hatx, s2haty, s2hatz);
3697  //do not need to perform explicitly the rotation on J
3698  //ROTATEZ(phiJL - LAL_PI, Jhatx, Jhaty, Jhatz);
3699 
3700  /* The cosinus of the angle between L and N is the scalar
3701  * product of the two vectors.
3702  * We do not need to perform additional rotation to compute it.
3703  */
3704  REAL8 Nx=0.;
3705  REAL8 Ny=sin(thetaJN);
3706  REAL8 Nz=cos(thetaJN);
3707  *incl=acos(Nx*LNhx+Ny*LNhy+Nz*LNhz); //output
3708 
3709  /* Rotation 4-5: Now J is along z and N in y-z plane, inclined from J
3710  * by thetaJN and with >ve component along y.
3711  * Now we bring L into the z axis to get spin components.
3712  */
3713  REAL8 thetaLJ = acos(LNhz);
3714  REAL8 phiL = atan2(LNhy, LNhx);
3715 
3716  ROTATEZ(-phiL, s1hatx, s1haty, s1hatz);
3717  ROTATEZ(-phiL, s2hatx, s2haty, s2hatz);
3718  ROTATEZ(-phiL, Nx, Ny, Nz);
3719  // do not need to perform explicitly the rotations on L and J
3720  //ROTATEZ(-phiL, LNhx, LNhy, LNhz);
3721  //ROTATEZ(-phiL, Jhatx, Jhaty, Jhatz);
3722 
3723  ROTATEY(-thetaLJ, s1hatx, s1haty, s1hatz);
3724  ROTATEY(-thetaLJ, s2hatx, s2haty, s2hatz);
3725  ROTATEY(-thetaLJ, Nx, Ny, Nz);
3726  // do not need to perform explicitly the rotations on L and J
3727  //ROTATEY(-thetaLJ, LNhx, LNhy, LNhz);
3728  //ROTATEY(-thetaLJ, Jhatx, Jhaty, Jhatz);
3729 
3730  /* Rotation 6: Now L is along z and we have to bring N
3731  * in the y-z plane with >ve y components.
3732  */
3733  REAL8 phiN = atan2(Ny, Nx);
3734  //Note the extra -phiRef here:
3735  // output spins must be given wrt to two body separations
3736  // which are rigidly rotated with spins
3737  ROTATEZ(LAL_PI/2.-phiN-phiRef, s1hatx, s1haty, s1hatz);
3738  ROTATEZ(LAL_PI/2.-phiN-phiRef, s2hatx, s2haty, s2hatz);
3739  // do not need to perform explicitly the rotations on L, J and N
3740  //ROTATEZ(LAL_PI/2.-phiN, LNhx, LNhy, LNhz);
3741  //ROTATEZ(LAL_PI/2.-phiN, Nx, Ny, LNz);
3742  //ROTATEZ(LAL_PI/2.-phiN, Jhatx, Jhaty, Jhatz);
3743 
3744  /* Set pointers to rotated spin vectors */
3745  *S1x = s1hatx*chi1;
3746  *S1y = s1haty*chi1;
3747  *S1z = s1hatz*chi1;
3748  *S2x = s2hatx*chi2;
3749  *S2y = s2haty*chi2;
3750  *S2z = s2hatz*chi2;
3751 
3752  //Uncomment the following lines for a check of the rotation
3753  /*printf("*****************************************\n");
3754  printf("** Check of TransformPrec...Conditions **\n");
3755  printf("*****************************************\n");
3756  //Rot 1:
3757  ROTATEZ(-phi0, Jhatx, Jhaty, Jhatz);
3758  //Rot 2:
3759  ROTATEY(-theta0, Jhatx, Jhaty, Jhatz);
3760  //Rot 3:
3761  ROTATEZ(phiJL - LAL_PI, Jhatx, Jhaty, Jhatz);
3762  //Rot 4:
3763  ROTATEZ(-phiL, Nx, Ny, Nz);
3764  ROTATEZ(-phiL, LNhx, LNhy, LNhz);
3765  ROTATEZ(-phiL, Jhatx, Jhaty, Jhatz);
3766  //Rot 5:
3767  ROTATEY(-thetaLJ, Nx, Ny, Nz);
3768  ROTATEY(-thetaLJ, LNhx, LNhy, LNhz);
3769  ROTATEY(-thetaLJ, Jhatx, Jhaty, Jhatz);
3770  //Rot 6:
3771  ROTATEZ(LAL_PI/2.-phiN, Nx, Ny, Nz);
3772  ROTATEZ(LAL_PI/2.-phiN, LNhx, LNhy, LNhz);
3773  ROTATEZ(LAL_PI/2.-phiN, Jhatx, Jhaty, Jhatz);
3774  printf("LNhat: %12.4e %12.4e %12.4e\n",LNhx,LNhy,LNhz);
3775  printf(" %12.4e %12.4e %12.4e\n",0.,0.,1.);
3776  printf("N: %12.4e %12.4e %12.4e\n",Nx,Ny,Nz);
3777  printf(" %12.4e %12.4e %12.4e\n",0.,sin(*incl),cos(*incl));
3778  printf("J.Lhat i: %12.4e f: %12.4e\n",Jz,Jnorm*Jhatz);
3779  printf("S1.L i: %12.4e f: %12.4e\n",chi1*cos(theta1),*S1z);
3780  printf("S2.L i: %12.4e f: %12.4e\n",chi2*cos(theta2),*S2z);
3781  printf("S1.S2 i: %12.4e f: %12.4e\n",chi1*chi2*(sin(theta1)*sin(theta2)*cos(phi12)+cos(theta1)*cos(theta2)),(*S1x)*(*S2x)+(*S1y)*(*S2y)+(*S1z)*(*S2z));
3782  printf("S1.J i: %12.4e f: %12.4e\n",chi1*(sin(theta1)*Jx+cos(theta1)*Jz),Jnorm*((*S1x)*Jhatx+(*S1y)*Jhaty+(*S1z)*Jhatz));
3783  printf("S2.J i: %12.4e f: %12.4e\n",chi2*(sin(theta2)*(cos(phi12)*Jx+sin(phi12)*Jy)+cos(theta2)*Jz),Jnorm*((*S2x)*Jhatx+(*S2y)*Jhaty+(*S2z)*Jhatz));
3784  printf("Jhat.Nhat i: %12.4e f: %12.4e\n",cos(thetaJN),Jhatx*Nx+Jhaty*Ny+Jhatz*Nz);
3785  printf("Norm Jhat: %12.4e norm N: %12.4e\n",Jhatx*Jhatx+Jhaty*Jhaty+Jhatz*Jhatz,Nx*Nx+Ny*Ny+Nz*Nz);
3786  printf("*****************************************\n");*/
3787  return XLAL_SUCCESS;
3788 }
3789 
3790 /**
3791  * @ingroup lalsimulation_inference
3792  * @brief inverse to XLALSimInspiralTransformPrecessingNewInitialConditions()
3793  *
3794  * @details This function performs inverse transformation to
3795  * XLALSimInspiralTransformPrecessingNewInitialConditions()
3796  * it takes as input waveform parameters, assume to be defined in the
3797  * L=z, n=x (L-robital momentum at fRef, n is orbital separation at fRef.
3798  * Direction of propagation (direction to the observer) N is defined by spherical angles
3799  * (pi/2-phiRef, inclination).
3800  * The return parameters are what is used in PE for sampling (see description in ....)
3801  * Note that the masses are in *solar mass* and |L| is computed to the same order as in the
3802  * direct function above. Spins are dimensionless.
3803  */
3804 
3805 /** @{ */
3806 
3808  REAL8 *thetaJN, /**< zenith angle between J and N (rad) [return]*/
3809  REAL8 *phiJL, /**< azimuthal angle of L_N on its cone about J (rad) [return] */
3810  REAL8 *theta1, /**< zenith angle between S1 and LNhat (rad) [return] */
3811  REAL8 *theta2, /**< zenith angle between S2 and LNhat (rad) [return] */
3812  REAL8 *phi12, /**< difference in azimuthal angle btwn S1, S2 (rad) [return] */
3813  REAL8 *chi1, /**< dimensionless spin of body 1 */
3814  REAL8 *chi2, /**< dimensionless spin of body 2 */
3815  const REAL8 incl, /**< Inclination angle of L_N (returned) */
3816  const REAL8 S1x, /**< S1 x component (input) */
3817  const REAL8 S1y, /**< S1 y component (input) */
3818  const REAL8 S1z, /**< S1 z component (input) */
3819  const REAL8 S2x, /**< S2 x component (input) */
3820  const REAL8 S2y, /**< S2 y component (input) */
3821  const REAL8 S2z, /**< S2 z component (input) */
3822  const REAL8 m1, /**< mass of body 1 (solar mass) */
3823  const REAL8 m2, /**< mass of body 2 (solar mass) */
3824  const REAL8 fRef, /**< reference GW frequency (Hz) */
3825  const REAL8 phiRef /**< reference orbital phase */
3826  )
3827 {
3828  /* Check that fRef is sane */
3829  if( fRef == 0. )
3830  {
3831  XLALPrintError("XLAL Error - %s: fRef=0 is invalid. Please pass in the starting GW frequency instead.\n", __func__);
3833  }
3834 
3835  REAL8 eta, v0, Jnorm, tmp1, tmp2; // theta0, phi0, Jnorm, tmp1, tmp2;
3836  REAL8 Jhatx, Jhaty, Jhatz, LNhx, LNhy, LNhz, Jx, Jy, Jz, Lmag;
3837  REAL8 s1hatx,s1haty,s1hatz,s2hatx,s2haty,s2hatz;
3838  REAL8 phi1, phi2, thetaJL, phiJ;
3839  REAL8 s1x, s1y, s1z, s2x, s2y, s2z;
3840  REAL8 Nx, Ny, Nz, phiO, phiN;
3841 
3842  /* Starting frame: LNhat is along the z-axis and the unit
3843  * spin vectors are defined from the angles relative to LNhat.
3844  */
3845 
3846  LNhx = 0.;
3847  LNhy = 0.;
3848  LNhz = 1.;
3849  *chi1 = sqrt(S1x*S1x + S1y*S1y + S1z*S1z);
3850  *chi2 = sqrt(S2x*S2x + S2y*S2y + S2z*S2z);
3851  if ((*chi1) > 0.0){
3852  s1hatx = S1x/(*chi1);
3853  s1haty = S1y/(*chi1);
3854  s1hatz = S1z/(*chi1);
3855  }else{
3856  s1hatx = 0.0;
3857  s1haty = 0.0;
3858  s1hatz = 0.0;
3859  }
3860 
3861  if ((*chi2) > 0.0){
3862  s2hatx = S2x/(*chi2);
3863  s2haty = S2y/(*chi2);
3864  s2hatz = S2z/(*chi2);
3865  }else{
3866  s2hatx = 0.0;
3867  s2haty = 0.0;
3868  s2hatz = 0.0;
3869  }
3870 
3871  phi1 = atan2(s1haty, s1hatx);
3872  phi2 = atan2(s2haty, s2hatx);
3873 
3874  *phi12 = phi2 - phi1;
3875  if (*phi12 < 0.0){
3876  *phi12 += 2.0*LAL_PI;
3877  }
3878  *theta1 = acos(s1hatz);
3879  *theta2 = acos(s2hatz);
3880 
3881  eta=m1*m2/(m1+m2)/(m1+m2);
3882  // v parameter at reference point
3883  v0 = cbrt( (m1+m2) * LAL_MTSUN_SI *LAL_PI * fRef );
3884 
3885  /* Define S1, S2, J with proper magnitudes */
3886  Lmag = XLALSimInspiralLN(m1+m2,eta,v0)*(1.0 + v0*v0*XLALSimInspiralL_2PN(eta));
3887  s1x = m1 * m1 * S1x;
3888  s1y = m1 * m1 * S1y;
3889  s1z = m1 * m1 * S1z;
3890  s2x = m2 * m2 * S2x;
3891  s2y = m2 * m2 * S2y;
3892  s2z = m2 * m2 * S2z;
3893  Jx = s1x + s2x;
3894  Jy = s1y + s2y;
3895  Jz = Lmag * LNhz + s1z + s2z;
3896 
3897  /* Normalize J to Jhat, find its angles in starting frame */
3898  Jnorm = sqrt( Jx*Jx + Jy*Jy + Jz*Jz);
3899  Jhatx = Jx / Jnorm;
3900  Jhaty = Jy / Jnorm;
3901  Jhatz = Jz / Jnorm;
3902 
3903  thetaJL = acos(Jhatz);
3904  phiJ = atan2(Jhaty, Jhatx);
3905 
3906  phiO = 0.5*LAL_PI - phiRef;
3907  Nx = sin(incl)*cos(phiO);
3908  Ny = sin(incl)*sin(phiO);
3909  Nz = cos(incl);
3910 
3911  *thetaJN = acos(Jhatx*Nx + Jhaty*Ny + Jhatz*Nz);
3912 
3913  /* The easiest way to define the phiJL is to rotate to the frame
3914  * where J is along z and N is in the y-z plane */
3915  ROTATEZ(-phiJ, Nx, Ny, Nz);
3916  ROTATEY(-thetaJL, Nx, Ny, Nz);
3917 
3918  ROTATEZ(-phiJ, LNhx, LNhy, LNhz);
3919  ROTATEY(-thetaJL, LNhx, LNhy, LNhz);
3920  /* You can check the rotation by uncommenting the lines below*/
3921  /*ROTATEZ(-phiJ, Jhatx, Jhaty, Jhatz);
3922  ROTATEY(-thetaJL, Jhatx, Jhaty, Jhatz);*/
3923 
3924  phiN = atan2(Ny, Nx);
3925  /* N in J-frame should be in y-z plane
3926  * After rotation defined below N should be in y-z plane inclined by thetaJN to J=z*/
3927  /*ROTATEZ(0.5*LAL_PI - phiN, Nx, Ny, Nz);*/
3928  ROTATEZ(0.5*LAL_PI - phiN, LNhx, LNhy, LNhz);
3929 
3930  *phiJL = atan2(LNhy, LNhx);
3931 
3932  if (*phiJL < 0.0){
3933  *phiJL += 2.0*LAL_PI;
3934  }
3935 
3936  /* That's all folks */
3937  return XLAL_SUCCESS;
3938 
3939 }
3940 
3941 /** @} */
3942 
3943 /**
3944  * @name Routines for Handling Approximants, Order, Axis, Mode Information
3945  * @{
3946  */
3947 
3948 /**
3949  * Checks whether the given approximant is implemented in lalsimulation's XLALSimInspiralChooseTDWaveform().
3950  *
3951  * returns 1 if the approximant is implemented, 0 otherwise.
3952  */
3954  Approximant approximant /**< post-Newtonian approximant for use in waveform production */
3955  )
3956 {
3957  switch (approximant)
3958  {
3959  case TaylorEt:
3960  case TaylorT1:
3961  case TaylorT2:
3962  case TaylorT3:
3963  case TaylorT4:
3964  case EccentricTD:
3965  case EOBNRv2:
3966  case HGimri:
3967  case IMRPhenomA:
3968  case EOBNRv2HM:
3969  case SpinTaylorT5:
3970  case SpinTaylorT4:
3971  case SpinTaylorT1:
3972  case IMRPhenomB:
3973  case PhenSpinTaylor:
3974  case IMRPhenomC:
3975  case IMRPhenomD:
3976  case IMRPhenomHM:
3977  case IMRPhenomPv2:
3978  case IMRPhenomPv3:
3979  case IMRPhenomPv3HM:
3980  case IMRPhenomPv2_NRTidal:
3982  case IMRPhenomNSBH:
3983  case IMRPhenomD_NRTidalv2:
3984  case IMRPhenomXAS:
3986  case IMRPhenomXHM:
3987  case IMRPhenomXP:
3988  case IMRPhenomXP_NRTidalv2:
3989  case IMRPhenomXPHM:
3990  case PhenSpinTaylorRD:
3991  case SEOBNRv1:
3992  case SpinDominatedWf:
3993  case SEOBNRv2:
3994  case SEOBNRv2_opt:
3995  case SEOBNRv3:
3996  case SEOBNRv3_pert:
3997  case SEOBNRv3_opt:
3998  case SEOBNRv3_opt_rk4:
3999  case SEOBNRv4:
4000  case SEOBNRv4_opt:
4001  case SEOBNRv4P:
4002  case SEOBNRv4PHM:
4003  case SEOBNRv2T:
4004  case SEOBNRv4T:
4007  case NR_hdf5:
4008  case NRSur7dq2:
4009  case NRSur7dq4:
4010  case TEOBResum_ROM:
4011  case TEOBResumS:
4012  case SEOBNRv4HM:
4013  case NRHybSur3dq8:
4014  case IMRPhenomT:
4015  case IMRPhenomTHM:
4016  case IMRPhenomTP:
4017  case IMRPhenomTPHM:
4018  case IMRPhenomXO4a:
4019  case ExternalPython:
4020  case SEOBNRv4HM_PA:
4021  case pSEOBNRv4HM_PA:
4022  return 1;
4023 
4024  default:
4025  return 0;
4026  }
4027 }
4028 
4029 /**
4030  * Checks whether the given approximant is implemented in lalsimulation's XLALSimInspiralChooseFDWaveform().
4031  *
4032  *
4033  * returns 1 if the approximant is implemented, 0 otherwise.
4034  */
4036  Approximant approximant /**< post-Newtonian approximant for use in waveform production */
4037  )
4038 {
4039  switch (approximant)
4040  {
4041  case IMRPhenomA:
4042  case IMRPhenomB:
4043  case IMRPhenomC:
4044  case IMRPhenomD:
4045  case IMRPhenomD_NRTidal:
4046  case IMRPhenomD_NRTidalv2:
4047  case IMRPhenomNSBH:
4048  case IMRPhenomHM:
4049  case IMRPhenomP:
4050  case IMRPhenomPv2:
4051  case IMRPhenomPv2_NRTidal:
4053  case IMRPhenomXAS:
4055  case IMRPhenomXHM:
4056  case IMRPhenomXP:
4057  case IMRPhenomXP_NRTidalv2:
4058  case IMRPhenomXPHM:
4059  case EOBNRv2_ROM:
4060  case EOBNRv2HM_ROM:
4067  case SEOBNRv4_ROM:
4068  case SEOBNRv4HM_ROM:
4069  case SEOBNRv4_ROM_NRTidal:
4072  case SEOBNRv4T_surrogate:
4073  case SEOBNRv5_ROM:
4074  case SEOBNRv5HM_ROM:
4075  //case TaylorR2F4:
4076  case TaylorF2:
4077  case TaylorF2Ecc:
4078  case TaylorF2NLTides:
4079  case EccentricFD:
4080  case SpinTaylorF2:
4081  case TaylorF2RedSpin:
4082  case TaylorF2RedSpinTidal:
4083  case SpinTaylorT4Fourier:
4084  case SpinTaylorT5Fourier:
4085  case NRSur4d2s:
4086  case IMRPhenomPv3:
4087  case IMRPhenomPv3HM:
4088  case ExternalPython:
4089  case IMRPhenomXO4a:
4090  return 1;
4091 
4092  default:
4093  return 0;
4094  }
4095 }
4096 
4097 /**
4098  * @brief Parses a waveform string to determine approximant, PN order, and axis choice.
4099  * @details
4100  * A waveform string can contain substrings specifying the approximant,
4101  * the PN order, and the frame axis. This routine decomposes the waveform
4102  * string to extract this information. Here we assume that there are no
4103  * extraneous characters in the waveform string that do not encode this
4104  * information. If extra characters are detected then this routine returns
4105  * a failure code.
4106  *
4107  * If one of the output parameters is set to NULL, this routine does not
4108  * return the value for that parameter, and does not fail if that parameter
4109  * cannot be determined from the waveform string; however, the full waveform
4110  * string must be valid. If the axis parameter is not NULL but information
4111  * about the frame axis is not found in the string then the default value
4112  * axis is set to the default value LAL_SIM_INSPIRAL_FRAME_AXIS_VIEW.
4113  * However, if the approximant or order parameters are not NULL and
4114  * the approximant and order cannot be determined from the waveform string,
4115  * then this routine produces an error.
4116  *
4117  * Parsing is not case sensitive (using the "C" locale).
4118  *
4119  * @param[out] approximant The approximate value from Approximate enum.
4120  * @param[out] order The PN order value from LALPNOrder enum.
4121  * @param[out] axis The frame axis value from LALPNOrder enum.
4122  * @param[in] waveform The waveform string.
4123  * @retval 0 Success.
4124  * @retval <0 Failure.
4125  *
4126  * @note
4127  * Users of the SWIG-Python interface probably want to use the routines
4128  * XLALSimInspiralGetApproximantFromString(),
4129  * XLALSimInspiralGetPNOrderFromString(), and
4130  * XLALSimInspiralGetFrameAxisFromString()
4131  * since there is no way to disable required matching of the PN order
4132  * with the SWIG-wrapped version of this routine.
4133  */
4134 int XLALSimInspiralDecomposeWaveformString(int *approximant, int *order, int *axis, const char *waveform)
4135 {
4136  char *string;
4137  int found_approximant, found_order, found_axis;
4138  int failed = 0;
4139 
4140  if (!waveform)
4142 
4143  string = XLALStringDuplicate(waveform);
4144 
4145 #define DELETE_SUBSTRING_IN_LIST_FROM_STRING(string, list) delete_substring_in_list_from_string(string, list, sizeof(list)/sizeof(*list))
4149 #undef DELETE_SUBSTRING_IN_LIST_FROM_STRING
4150 
4151  /* assign values to output parameters */
4152  if (approximant) {
4153  *approximant = found_approximant;
4154  /* fail if couldn't find approximant */
4155  if (found_approximant < 0)
4156  failed = 1;
4157  }
4158  if (order) {
4159  *order = found_order;
4160  /* fail if couldn't find order */
4161  if (found_order < 0)
4162  failed = 1;
4163  }
4164  if (axis) {
4165  *axis = found_axis;
4166  /* set frame axis to view if couldn't find, but don't fail */
4167  if (found_axis < 0)
4169  }
4170 
4171  /* check to see if there are extra characters */
4172  if (strspn(string, "\b") != strlen(string))
4173  failed = 1;
4174 
4175  XLALFree(string);
4176 
4177  if (failed)
4178  XLAL_ERROR(XLAL_EINVAL, "Invalid waveform string `%s'.", waveform);
4179  return 0;
4180 }
4181 
4182 /**
4183  * @brief Parses a waveform string to determine approximant.
4184  * @details
4185  * This routine uses XLALSimInspiralDecomposeWaveformString() to
4186  * determine the approximant from the waveform string.
4187  * @param[in] waveform The waveform string.
4188  * @return The Approximant enum value, or -1 on error.
4189  */
4191 {
4192  int approximant = -1;
4194  {
4195  approximant = -1;
4197  }
4198  return approximant;
4199 }
4200 
4201 /**
4202  * @deprecated
4203  * Like XLALSimInspiralGetApproximantFromString() but doesn't demand that the
4204  * remainder of the waveform string be valid.
4205  */
4206 int XLALGetApproximantFromString(const char *waveform)
4207 {
4208  int approximant = -1;
4209  int errnum = 0;
4210  XLAL_PRINT_DEPRECATION_WARNING("XLALSimInspiralGetApproximantFromString");
4211  XLAL_TRY(XLALSimInspiralDecomposeWaveformString(&approximant, NULL, NULL, waveform), errnum);
4212  if (errnum && errnum != XLAL_EINVAL) // pass any error other than XLAL_EINVAL
4213  XLAL_ERROR(errnum);
4214  /* fail if approximant wasn't found */
4215  if (approximant < 0)
4216  XLAL_ERROR(XLAL_EINVAL, "Cannot parse approximant from string `%s'.", waveform);
4217  return approximant;
4218 }
4219 
4220 /**
4221  * @brief Parses a waveform string to determine PN order.
4222  * @details
4223  * This routine uses XLALSimInspiralDecomposeWaveformString() to
4224  * determine the PN order from the waveform string.
4225  * @param[in] waveform The waveform string.
4226  * @return The LALPNOrder enum value, or -1 on error.
4227  */
4228 int XLALSimInspiralGetPNOrderFromString(const char *waveform)
4229 {
4230  int order = -1;
4231  if (XLALSimInspiralDecomposeWaveformString(NULL, &order, NULL, waveform) < 0)
4233  return order;
4234 }
4235 
4236 /**
4237  * @deprecated
4238  * Like XLALSimInspiralGetPNOrderFromString() but doesn't demand that the
4239  * remainder of the waveform string be valid.
4240  */
4241 int XLALGetOrderFromString(const char *waveform)
4242 {
4243  int order = -1;
4244  int errnum = 0;
4245  XLAL_PRINT_DEPRECATION_WARNING("XLALSimInspiralGetPNOrderFromString");
4246  XLAL_TRY(XLALSimInspiralDecomposeWaveformString(NULL, &order, NULL, waveform), errnum);
4247  if (errnum && errnum != XLAL_EINVAL) // pass any error other than XLAL_EINVAL
4248  XLAL_ERROR(errnum);
4249  /* fail if order wasn't found */
4250  if (order < 0)
4251  XLAL_ERROR(XLAL_EINVAL, "Cannot parse approximant from string `%s'.", waveform);
4252  return order;
4253 }
4254 
4255 /**
4256  * @brief Parses a waveform string to determine frame axis.
4257  * @details
4258  * This routine uses XLALSimInspiralDecomposeWaveformString() to
4259  * determine the frame axis from the waveform string. If the
4260  * frame axis cannot be determined, the value
4261  * LAL_SIM_INSPIRAL_FRAME_AXIS_VIEW is returned.
4262  * @param[in] waveform The waveform string.
4263  * @return The LALPNOrder enum value, or -1 on error.
4264  */
4265 int XLALSimInspiralGetFrameAxisFromString(const char *waveform)
4266 {
4267  int axis = -1;
4268  if (XLALSimInspiralDecomposeWaveformString(NULL, NULL, &axis, waveform) < 0)
4270  return axis;
4271 }
4272 
4273 /**
4274  * @deprecated
4275  * Like XLALSimInspiralGetFrameAxisFromString() but doesn't demand that the
4276  * remainder of the waveform string be valid.
4277  */
4278 int XLALGetFrameAxisFromString(const char *waveform)
4279 {
4280  int axis = -1;
4281  int errnum = 0;
4282  XLAL_PRINT_DEPRECATION_WARNING("XLALSimInspiralGetFrameAxisFromString");
4283  XLAL_TRY(XLALSimInspiralDecomposeWaveformString(NULL, NULL, &axis, waveform), errnum);
4284  if (errnum && errnum != XLAL_EINVAL) // pass any error other than XLAL_EINVAL
4285  XLAL_ERROR(errnum);
4286  /* if axis wasn't found, use view */
4287  if (axis < 0)
4289  return axis;
4290 }
4291 
4292 /**
4293  * @brief Parses a string to determine the LALSimInspiralApplyTaper enum value.
4294  * @details
4295  * Parses a string to determine the LALSimInspiralApplyTaper enum value.
4296  * Parsing is not case sensitive (using the "C" locale).
4297  * @param[in] string The string to be parsed.
4298  * @return The LALSimInspiralApplyTaper enum value, or -1 on error.
4299  */
4300 int XLALSimInspiralGetTaperFromString(const char *string)
4301 {
4302  const char **list = lalSimulationTaperNames;
4303  size_t size = sizeof(lalSimulationTaperNames)/sizeof(*lalSimulationTaperNames);
4304  size_t i;
4305 
4306  if (!string)
4308 
4309  for (i = 0; i < size; ++i)
4310  if (list[i])
4311  if (XLALStringCaseCompare(string, list[i]) == 0) // found it
4312  return i;
4313 
4314  XLAL_ERROR(XLAL_EINVAL, "Invalid injection tapering string `%s'.", string);
4315 }
4316 
4317 /**
4318  * @deprecated
4319  * Use XLALSimInspiralGetTaperFromString() instead.
4320  */
4321 int XLALGetTaperFromString(const char *string)
4322 {
4323  XLAL_PRINT_DEPRECATION_WARNING("XLALSimInspiralGetTaperFromString");
4324  return XLALSimInspiralGetTaperFromString(string);
4325 }
4326 
4327 /**
4328  * @brief Parses a string to determine the LALSimInspiralModesChoice enum value.
4329  * @details
4330  * Parses a string to determine the LALSimInspiralModesChoice enum value.
4331  * Parsing is not case sensitive (using the "C" locale).
4332  * @param[in] string The string to be parsed.
4333  * @return The LALSimInspiralModesChoice enum value, or 0 on error.
4334  * @note The normal error code -1 is actually a valid mode choice
4335  * so this routine returns 0 (which is not a valid modes choice)
4336  * on error rather than -1.
4337  */
4339 {
4340  const char **list = lalSimulationModesChoiceNames;
4341  size_t size = sizeof(lalSimulationModesChoiceNames)/sizeof(*lalSimulationModesChoiceNames);
4342  size_t i;
4343 
4344  if (!string)
4346 
4347  /* the "ALL" case is a special case */
4348  if (XLALStringCaseCompare(string, "ALL") == 0)
4350 
4351  for (i = 0; i < size; ++i)
4352  if (list[i])
4353  if (XLALStringCaseCompare(string, list[i]) == 0) // found it
4354  return i;
4355 
4356  XLAL_ERROR_VAL(0, XLAL_EINVAL, "Invalid injection modes choice string `%s'.", string);
4357 }
4358 
4359 /**
4360  * @deprecated
4361  * Use XLALSimInspiralHigherModesFromString() instead.
4362  */
4363 int XLALGetHigherModesFromString(const char *string)
4364 {
4365  XLAL_PRINT_DEPRECATION_WARNING("XLALSimInspiralGetHigherModesFromString");
4367 }
4368 
4369 /**
4370  * @brief Returns a string associated with an Approximant enum value.
4371  * @param[in] approximant The Approximant enum value.
4372  * @returns A constant string or NULL if there is an error.
4373  */
4375 {
4376  const char *s;
4377  if ((int)(approximant) < 0 || (int)(approximant) >= NumApproximants)
4380  if (!s)
4382  return s;
4383 }
4384 
4385 /**
4386  * @deprecated
4387  * Use XLALSimInspiralHigherModesFromString() instead.
4388  */
4390 {
4391  XLAL_PRINT_DEPRECATION_WARNING("XLALSimInspiralGetStringFromApproximant");
4393 }
4394 
4395 /**
4396  * @brief Returns a string associated with a LALPNOrder enum value.
4397  * @param[in] order The LALPNOrder enum value.
4398  * @returns A constant string or NULL if there is an error.
4399  */
4401 {
4402  const char *s;
4403  if ((int)(order) < 0 || (int)(order) >= LAL_PNORDER_NUM_ORDER)
4405  s = lalSimulationPNOrderNames[order];
4406  if (!s)
4408  return s;
4409 }
4410 
4411 /**
4412  * @brief Returns a string associated with a LALSimInspiralApplyTaper enum value.
4413  * @param[in] taper The LALSimInspiralApplyTaper enum value.
4414  * @returns A constant string or NULL if there is an error.
4415  */
4417 {
4418  const char *s;
4419  if ((int)(taper) < 0 || (int)(taper) >= LAL_SIM_INSPIRAL_TAPER_NUM_OPTS)
4421  s = lalSimulationTaperNames[taper];
4422  if (!s)
4424  return s;
4425 }
4426 
4427 /**
4428  * @brief Returns a string associated with a LALSimInspiralFrameAxis enum value.
4429  * @param[in] axis The LALSimInspiralFrameAxis enum value.
4430  * @returns A constant string or NULL if there is an error.
4431  */
4433 {
4434  const char *s;
4435  if ((int)(axis) < 0 || (size_t)(axis) >= sizeof(lalSimulationFrameAxisNames)/sizeof(*lalSimulationFrameAxisNames))
4438  if (!s)
4440  return s;
4441 }
4442 
4443 /**
4444  * @brief Returns a string associated with a LALSimInspiralModesChoice enum value.
4445  * @param[in] modes The LALSimInspiralModesChoice enum value.
4446  * @returns A constant string or NULL if there is an error.
4447  */
4449 {
4450  const char *s;
4451  if (modes == LAL_SIM_INSPIRAL_MODES_CHOICE_ALL) // handle this case separately
4452  return "ALL";
4453  if ((int)(modes) < 0 || (size_t)(modes) >= sizeof(lalSimulationModesChoiceNames)/sizeof(*lalSimulationModesChoiceNames))
4456  if (!s)
4458  return s;
4459 }
4460 
4462 
4464  switch (approx)
4465  {
4466  case SpinTaylor:
4467  case SpinTaylorFrameless:
4468  case SpinTaylorT1:
4469  case SpinTaylorT4:
4470  case SpinTaylorT5:
4471  case PhenSpinTaylor:
4472  case PhenSpinTaylorRD:
4473  case SpinTaylorT3:
4474  case IMRPhenomP:
4475  case IMRPhenomPv2:
4476  case IMRPhenomPv2_NRTidal:
4478  case IMRPhenomPv3:
4479  case IMRPhenomPv3HM:
4480  case IMRPhenomXP:
4481  case IMRPhenomXP_NRTidalv2:
4482  case IMRPhenomXPHM:
4483  case SpinTaylorT5Fourier:
4484  case SpinTaylorT4Fourier:
4485  case SpinDominatedWf:
4486  case SEOBNRv3:
4487  case SEOBNRv3_pert:
4488  case SEOBNRv3_opt:
4489  case SEOBNRv3_opt_rk4:
4490  case SEOBNRv4P:
4491  case SEOBNRv4PHM:
4492  case NR_hdf5:
4493  case NRSur4d2s:
4494  case NRSur7dq2:
4495  case NRSur7dq4:
4496  case IMRPhenomTP:
4497  case IMRPhenomTPHM:
4498  case IMRPhenomXO4a:
4499  spin_support=LAL_SIM_INSPIRAL_PRECESSINGSPIN;
4500  break;
4501  case SpinTaylorF2:
4502  case FindChirpPTF:
4503  case HGimri:
4504  spin_support=LAL_SIM_INSPIRAL_SINGLESPIN;
4505  break;
4506  case TaylorF2:
4507  case TaylorF2Ecc:
4508  case TaylorF2NLTides:
4509  case TaylorF2RedSpin:
4510  case TaylorF2RedSpinTidal:
4511  case IMRPhenomB:
4512  case IMRPhenomC:
4513  case IMRPhenomD:
4514  case IMRPhenomD_NRTidal:
4515  case IMRPhenomD_NRTidalv2:
4516  case IMRPhenomNSBH:
4517  case IMRPhenomHM:
4518  case IMRPhenomXAS:
4520  case IMRPhenomXHM:
4521  case SEOBNRv1:
4522  case SEOBNRv2:
4523  case SEOBNRv4:
4524  case SEOBNRv2_opt:
4525  case SEOBNRv4_opt:
4526  case SEOBNRv2T:
4527  case SEOBNRv4T:
4528  case SEOBNRv4HM:
4535  case SEOBNRv4_ROM:
4536  case SEOBNRv4HM_ROM:
4537  case SEOBNRv4_ROM_NRTidal:
4540  case SEOBNRv4T_surrogate:
4541  case SEOBNRv5_ROM:
4542  case SEOBNRv5HM_ROM:
4543  case TEOBResumS:
4544  case TaylorR2F4:
4545  case IMRPhenomFB:
4546  case FindChirpSP:
4547  case NRHybSur3dq8:
4548  case IMRPhenomT:
4549  case IMRPhenomTHM:
4550  case SEOBNRv4HM_PA:
4551  case pSEOBNRv4HM_PA:
4552  spin_support=LAL_SIM_INSPIRAL_ALIGNEDSPIN;
4553  break;
4554  case TaylorEt:
4555  case TaylorT1:
4556  case TaylorT2:
4557  case TaylorT3:
4558  case TaylorT4:
4559  case EccentricTD:
4560  case EccentricFD:
4561  case IMRPhenomA:
4562  case EOBNRv2HM:
4563  case EOBNRv2HM_ROM:
4564  case EOBNRv2:
4565  case EOBNRv2_ROM:
4566  case EOBNR:
4567  case EOB:
4568  case IMRPhenomFA:
4569  case GeneratePPN:
4570  case TEOBResum_ROM:
4571  spin_support=LAL_SIM_INSPIRAL_SPINLESS;
4572  break;
4573  case ExternalPython:
4575  break;
4576  default:
4577  XLALPrintError("Approximant not supported by lalsimulation TD/FD routines \n");
4579  }
4580 
4581  return spin_support;
4582 
4583 }
4584 
4586 
4588  switch (approx)
4589  {
4590  case SEOBNRv3:
4591  case SEOBNRv3_pert:
4592  case SEOBNRv3_opt:
4593  case SEOBNRv3_opt_rk4:
4594  case SEOBNRv4P:
4595  case SEOBNRv4PHM:
4596  spin_freq=LAL_SIM_INSPIRAL_SPINS_FLOW;
4597  break;
4598  case SpinTaylor:
4599  case SpinTaylorFrameless:
4600  case SpinTaylorT1:
4601  case SpinTaylorT4:
4602  case SpinTaylorT5:
4603  case PhenSpinTaylor:
4604  case PhenSpinTaylorRD:
4605  case SpinTaylorT3:
4606  case IMRPhenomP:
4607  case IMRPhenomPv2:
4608  case IMRPhenomPv3:
4609  case IMRPhenomPv3HM:
4610  case IMRPhenomPv2_NRTidal:
4612  case IMRPhenomXP:
4613  case IMRPhenomXP_NRTidalv2:
4614  case IMRPhenomXPHM:
4615  case SpinTaylorT5Fourier:
4616  case SpinTaylorT4Fourier:
4617  case SpinDominatedWf:
4618  case NRSur4d2s:
4619  case NRSur7dq2:
4620  case NRSur7dq4:
4621  case SpinTaylorF2:
4622  case IMRPhenomTP:
4623  case IMRPhenomTPHM:
4624  case IMRPhenomXO4a:
4625  spin_freq=LAL_SIM_INSPIRAL_SPINS_F_REF;
4626  break;
4627  case FindChirpPTF:
4628  case HGimri:
4629  case TaylorF2:
4630  case TaylorF2Ecc:
4631  case TaylorF2NLTides:
4632  case TaylorF2RedSpin:
4633  case TaylorF2RedSpinTidal:
4634  case IMRPhenomB:
4635  case IMRPhenomC:
4636  case IMRPhenomD:
4637  case IMRPhenomD_NRTidal:
4638  case IMRPhenomD_NRTidalv2:
4639  case IMRPhenomNSBH:
4640  case IMRPhenomHM:
4641  case IMRPhenomXAS:
4643  case IMRPhenomXHM:
4644  case SEOBNRv1:
4645  case SEOBNRv2:
4646  case SEOBNRv4:
4647  case SEOBNRv2_opt:
4648  case SEOBNRv4_opt:
4649  case SEOBNRv2T:
4650  case SEOBNRv4T:
4651  case SEOBNRv4HM:
4658  case SEOBNRv4_ROM:
4659  case SEOBNRv4_ROM_NRTidal:
4662  case SEOBNRv4T_surrogate:
4663  case SEOBNRv4HM_ROM:
4664  case SEOBNRv5_ROM:
4665  case SEOBNRv5HM_ROM:
4666  case TaylorR2F4:
4667  case IMRPhenomFB:
4668  case FindChirpSP:
4669  case NRHybSur3dq8:
4670  case TaylorEt:
4671  case TaylorT1:
4672  case TaylorT2:
4673  case TaylorT3:
4674  case TaylorT4:
4675  case EccentricTD:
4676  case EccentricFD:
4677  case IMRPhenomA:
4678  case EOBNRv2HM:
4679  case EOBNRv2HM_ROM:
4680  case EOBNRv2:
4681  case EOBNRv2_ROM:
4682  case EOBNR:
4683  case EOB:
4684  case IMRPhenomFA:
4685  case GeneratePPN:
4686  case TEOBResum_ROM:
4687  case IMRPhenomT:
4688  case IMRPhenomTHM:
4689  case TEOBResumS:
4690  case SEOBNRv4HM_PA:
4691  case pSEOBNRv4HM_PA:
4693  break;
4694  case NR_hdf5:
4695  case ExternalPython:
4697  break;
4698  default:
4699  XLALPrintError("Approximant not supported by lalsimulation TD/FD routines \n");
4701  }
4702 
4703  return spin_freq;
4704 
4705 }
4706 
4708 
4709  // Models for which LAL_SIM_INSPIRAL_ALLOW_ZERO_FMIN is set allow f_min=0,
4710  // which means that the full length of the waveform is returned. This means
4711  // that in XLALSimInspiralTD, XLALSimInspiralChooseTDWaveform is called
4712  // instead of XLALSimInspiralTDFromTD for these models. This also means that
4713  // the starting frequency is not altered (as done in XLALSimInspiralTDFromTD)
4714  // for these models, independent of what f_min is passed.
4715 
4717  switch (approx)
4718  {
4719  case NRSur7dq2:
4720  case NRSur7dq4:
4721  allow_zero_fmin=LAL_SIM_INSPIRAL_ALLOW_ZERO_FMIN;
4722  break;
4723  default:
4724  allow_zero_fmin=LAL_SIM_INSPIRAL_DISALLOW_ZERO_FMIN;
4725  }
4726 
4727  return allow_zero_fmin;
4728 
4729 }
4730 
4732 
4734  switch (approx)
4735  {
4736  case TaylorT1:
4737  case TaylorT2:
4738  case TaylorT3:
4739  case TaylorF1:
4740  case TaylorR2F4:
4741  case TaylorF2RedSpin:
4742  case TaylorF2RedSpinTidal:
4743  case PadeT1:
4744  case PadeF1:
4745  case EOB:
4746  case BCV:
4747  case BCVSpin:
4748  case SpinTaylorT1:
4749  case SpinTaylorT5:
4750  case SpinTaylorT3:
4751  case SpinTaylorT4:
4752  case SpinTaylorFrameless:
4753  case SpinTaylor:
4754  case SpinQuadTaylor:
4755  case FindChirpSP:
4756  case FindChirpPTF:
4757  case HGimri:
4758  case GeneratePPN:
4759  case BCVC:
4760  case FrameFile:
4761  case AmpCorPPN:
4762  case NumRel:
4763  case NumRelNinja2:
4764  case EOBNR:
4765  case EOBNRv2:
4766  case EOBNRv2_ROM:
4767  case EOBNRv2HM:
4768  case EOBNRv2HM_ROM:
4769  case TEOBResum_ROM:
4770  case SEOBNRv1:
4771  case SEOBNRv2:
4772  case SEOBNRv2_opt:
4773  case SEOBNRv3:
4774  case SEOBNRv3_pert:
4775  case SEOBNRv3_opt:
4776  case SEOBNRv3_opt_rk4:
4777  case SEOBNRv4:
4778  case SEOBNRv4_opt:
4779  case SEOBNRv4P:
4780  case SEOBNRv4PHM:
4781  case SEOBNRv2T:
4782  case SEOBNRv4T:
4783  case SEOBNRv4HM:
4790  case TEOBResumS:
4791  case IMRPhenomA:
4792  case IMRPhenomB:
4793  case IMRPhenomFA:
4794  case IMRPhenomFB:
4795  case IMRPhenomFC:
4796  case IMRPhenomNSBH:
4797  case SpinTaylorT5Fourier:
4798  case SpinTaylorT4Fourier:
4799  case TaylorEt:
4800  case TaylorT4:
4801  case TaylorN:
4802  case SpinDominatedWf:
4803  case NR_hdf5:
4804  case NRSur4d2s:
4805  case NRSur7dq2:
4806  case NRSur7dq4:
4807  case NRHybSur3dq8:
4808  case IMRPhenomT:
4809  case IMRPhenomTHM:
4810  case IMRPhenomTP:
4811  case IMRPhenomTPHM:
4812  case NumApproximants:
4813  case SEOBNRv4HM_PA:
4814  case IMRPhenomXO4a:
4815  testGR_accept=LAL_SIM_INSPIRAL_NO_TESTGR_PARAMS;
4816  break;
4817  case TaylorF2:
4818  case TaylorF2Ecc:
4819  case TaylorF2NLTides:
4820  case SpinTaylorF2:
4821  case EccentricFD:
4822  case Eccentricity:
4823  case PhenSpinTaylor:
4824  case PhenSpinTaylorRD:
4825  case EccentricTD:
4826  case SEOBNRv4_ROM:
4827  case SEOBNRv4HM_ROM:
4828  case SEOBNRv4_ROM_NRTidal:
4831  case SEOBNRv4T_surrogate:
4832  case SEOBNRv5_ROM:
4833  case SEOBNRv5HM_ROM:
4834  case IMRPhenomC:
4835  case IMRPhenomD:
4836  case IMRPhenomP:
4837  case IMRPhenomPv2:
4838  case IMRPhenomPv2_NRTidal:
4840  case IMRPhenomD_NRTidal:
4841  case IMRPhenomD_NRTidalv2:
4842  case IMRPhenomHM:
4843  case IMRPhenomPv3:
4844  case IMRPhenomPv3HM:
4845  case pSEOBNRv4HM_PA:
4846  case IMRPhenomXAS:
4847  case IMRPhenomXHM:
4848  case IMRPhenomXP:
4849  case IMRPhenomXPHM:
4851  case IMRPhenomXP_NRTidalv2:
4852  testGR_accept=LAL_SIM_INSPIRAL_TESTGR_PARAMS;
4853  break;
4854  case ExternalPython:
4856  break;
4857  default:
4858  XLALPrintError("Approximant not supported by lalsimulation TD/FD routines \n");
4860  }
4861  return testGR_accept;
4862 };
4863 
4864 /* Function for introducing Lorentz violating changes in FD phase; calculates eqns. 30 & 32 of arxiv 1110.2720 for the LV phase term in FD and multiplies to h+ and hx */
4866  COMPLEX16FrequencySeries **hptilde, /**< Frequency-domain waveform h+ */
4867  COMPLEX16FrequencySeries **hctilde, /**< Frequency-domain waveform hx */
4868  REAL8 m1, /**< Mass 1 in solar masses */
4869  REAL8 m2, /**< Mass 2 in solar masses */
4870  REAL8 r, /**< distance in metres*/
4871  LALDict *LALparams /**< LAL dictionary containing accessory parameters */
4872  )
4873 {
4874  REAL8 f0, f, df;
4875  COMPLEX16 hplus, hcross, tmpExp;
4876  REAL8 M, eta, zeta, dPhiPref, Mc, tmpVal;
4877  UINT4 len, i;
4878  M = m1+m2;
4879  eta = m1*m2/(M*M);
4880  Mc = M*pow(eta, 0.6);
4881  len = (*hptilde)->data->length;
4882 
4883  REAL8 lambda_eff = pow(10,XLALSimInspiralWaveformParamsLookupNonGRLIVLogLambdaEff(LALparams)); /* Effective wavelength-like parameter in phase in metres */
4884  REAL8 nonGR_alpha = XLALSimInspiralWaveformParamsLookupNonGRLIVAlpha(LALparams); /* Exponent defined in terms of PN order characterising LIV*/
4885  REAL8 LIV_A_sign = XLALSimInspiralWaveformParamsLookupNonGRLIVASign(LALparams); /* Sign of A determining the sign of LV phase */
4886 
4887  if ((*hctilde)->data->length != len) {
4888  XLALPrintError("Lengths of plus and cross polarization series do not agree \n");
4890  }
4891 
4892  f0 = (*hptilde)->f0;
4893  if ((*hctilde)->f0 != f0) {
4894  XLALPrintError("Starting frequencies of plus and cross polarization series do not agree \n");
4896  }
4897 
4898  df = (*hptilde)->deltaF;
4899  if ((*hctilde)->deltaF != df) {
4900  XLALPrintError("Frequency steps of plus and cross polarization series do not agree \n");
4902  }
4903 
4904  UINT4 k = 0;
4905  if (f0 == 0.0)
4906  k=1;
4907 
4908  if (nonGR_alpha == 1) {
4909  zeta = LIV_A_sign*LAL_PI*r/lambda_eff; /*Eqn. (32) of arxiv:1110.2720*/
4910  dPhiPref = zeta*log(LAL_PI*Mc*LAL_MTSUN_SI); /*Eqn. (31) of arxiv:1110.2720;the frequency dependence is treated below*/
4911  for (i=k; i<len; i++) {
4912  f = f0 + i*df;
4913  tmpExp = cexp(I*(dPhiPref + zeta*log(f)));
4914  hplus = (*hptilde)->data->data[i] * tmpExp;
4915  (*hptilde)->data->data[i] = hplus;
4916  hcross = (*hctilde)->data->data[i] * tmpExp;
4917  (*hctilde)->data->data[i] = hcross;
4918  }
4919  }
4920  else {
4921  zeta = LIV_A_sign*pow(LAL_PI, (2. - nonGR_alpha))*r*pow(Mc*LAL_MRSUN_SI, (1. - nonGR_alpha))/((1. - nonGR_alpha)*pow(lambda_eff, (2. - nonGR_alpha))); /*Eqn. (30) of arxiv:1110.2720*/
4922  dPhiPref = zeta*pow(LAL_PI*Mc*LAL_MTSUN_SI, (nonGR_alpha - 1.)); /*Eqn. (28) of arxiv:1110.2720;the frequency dependence is treated below*/
4923  for (i=k; i<len; i++) {
4924  f = f0 + i*df;
4925  tmpVal = pow(f, (nonGR_alpha - 1.));
4926  tmpExp=cexp(-I*dPhiPref*tmpVal);
4927  hplus = (*hptilde)->data->data[i] * tmpExp;
4928  (*hptilde)->data->data[i] = hplus;
4929  hcross = (*hctilde)->data->data[i] * tmpExp;
4930  (*hctilde)->data->data[i] = hcross;
4931  }
4932 
4933  }
4934  return XLAL_SUCCESS;
4935 }
4936 
4937 /** @} */
4938 
4939 /**
4940  * @name Routines Determining Waveform Durations and Frequencies
4941  * @{
4942  */
4943 
4944 /**
4945  * @brief Routine to compute an overestimate of the inspiral time from a given frequency.
4946  * @details
4947  * This routine estimates the time it will take for point-particle inspiral from a
4948  * specified frequency to infinite frequency. The estimate is intended to be an
4949  * over-estimate, so that the true inspiral time is always smaller than the time this
4950  * routine returns. To obtain this estimate, the 2pN chirp time is used where all
4951  * negative contributions are discarded.
4952  * @param fstart The starting frequency in Hz.
4953  * @param m1 The mass of the first component in kg.
4954  * @param m2 The mass of the second component in kg.
4955  * @param s1 The dimensionless spin of the first component.
4956  * @param s2 The dimensionless spin of the second component.
4957  * @return Upper bound on chirp time of post-Newtonian inspiral in seconds.
4958  */
4960 {
4961  double M = m1 + m2; // total mass
4962  double mu = m1 * m2 / M; // reduced mass
4963  double eta = mu / M; // symmetric mass ratio
4964  /* chi = (s1*m1 + s2*m2)/M <= max(|s1|,|s2|) */
4965  double chi = fabs(fabs(s1) > fabs(s2) ? s1 : s2); // over-estimate of chi
4966  /* note: for some reason these coefficients are named wrong...
4967  * "2PN" should be "1PN", "4PN" should be "2PN", etc. */
4968  double c0 = fabs(XLALSimInspiralTaylorT2Timing_0PNCoeff(M, eta));
4970  /* the 1.5pN spin term is in TaylorT2 is 8*beta/5 [Citation ??]
4971  * where beta = (113/12 + (25/4)(m2/m1))*(s1*m1^2/M^2) + 2 <-> 1
4972  * [Cutler & Flanagan, Physical Review D 49, 2658 (1994), Eq. (3.21)]
4973  * which can be written as (113/12)*chi - (19/6)(s1 + s2)
4974  * and we drop the negative contribution */
4975  double c3 = (226.0/15.0) * chi;
4976  /* there is also a 1.5PN term with eta, but it is negative so do not include it */
4977  double c4 = XLALSimInspiralTaylorT2Timing_4PNCoeff(eta);
4978  double v = cbrt(LAL_PI * LAL_G_SI * M * fstart) / LAL_C_SI;
4979  return c0 * pow(v, -8) * (1.0 + (c2 + (c3 + c4 * v) * v) * v * v);
4980 }
4981 
4982 /**
4983  * @brief Routine to compute an overestimate of the merger time.
4984  * @details
4985  * This routine provides an upper bound on the time it will take for compact
4986  * binaries to plunge and merge at the end of the quasi-stationary inspiral.
4987  * This is quite vague since the notion of a innermost stable circular orbit
4988  * is ill-defined except in a test mass limit. Nevertheless, this routine
4989  * assumes (i) that the innermost stable circular orbit occurs at v = c / 3,
4990  * or r = 9 G M / c^3 (in Boyer-Lindquist coordinates), which is roughly right
4991  * for an extreme Kerr black hole counter-rotating with a test particle,
4992  * and (ii) the plunge lasts for a shorter period than one cycle at this
4993  * innermost stable circular orbit.
4994  * @param m1 The mass of the first component in kg.
4995  * @param m2 The mass of the second component in kg.
4996  * @return Upper bound on the merger time in seconds.
4997  */
4999 {
5000  const double norbits = 1;
5001  double M = m1 + m2; // total mass
5002  double r = 9.0 * M * LAL_MRSUN_SI / LAL_MSUN_SI;
5003  double v = LAL_C_SI / 3.0;
5004  return norbits * (2.0 * LAL_PI * r / v);
5005 }
5006 
5007 /**
5008  * @brief Routine to compute an overestimate of the ringdown time.
5009  * @details
5010  * This routine provides an upper bound on the time it will take for a
5011  * black hole produced by compact binary merger to ring down through
5012  * quasinormal mode radiation. An approximate formula for the frequency
5013  * and quality of the longest-lived fundamental (n=0) dominant (l=m=2)
5014  * quasinormal mode * is given by Eqs. (E1) and (E2) along with Table VIII
5015  * of Berti, Cardoso, and Will, Physical Review D (2006) 064030.
5016  * Waveform generators produce 10 e-folds of ringdown radiation, so
5017  * this routine goes up to 11 to provide an over-estimate of the ringdown time.
5018  * @param M The mass of the final black hole in kg.
5019  * @param s The dimensionless spin of the final black hole.
5020  * @return Upper bound on the merger time in seconds.
5021  * @see Emanuele Berti, Vitor Cardoso, and Clifford M. Will, Physical Review D 73, 064030 (2006) DOI: 10.1103/PhysRevD.73.064030
5022  */
5024 {
5025  const double nefolds = 11; /* waveform generators only go up to 10 */
5026 
5027  /* these values come from Table VIII of Berti, Cardoso, and Will with n=0, m=2 */
5028  const double f1 = +1.5251;
5029  const double f2 = -1.1568;
5030  const double f3 = +0.1292;
5031  const double q1 = +0.7000;
5032  const double q2 = +1.4187;
5033  const double q3 = -0.4990;
5034 
5035  double omega = (f1 + f2 * pow(1.0 - s, f3)) / (M * LAL_MTSUN_SI / LAL_MSUN_SI);
5036  double Q = q1 + q2 * pow(1.0 - s, q3);
5037  double tau = 2.0 * Q / omega; /* see Eq. (2.1) of Berti, Cardoso, and Will */
5038  return nefolds * tau;
5039 }
5040 
5041 /**
5042  * @brief Routine to compute an overestimate of a final black hole dimensionless spin.
5043  * @details
5044  * This routine provides an upper bound on the dimensionless spin of a black
5045  * hole produced in a compact binary merger. Uses the formula in Tichy and
5046  * Marronetti, Physical Review D 78 081501 (2008), Eq. (1) and Table 1, for
5047  * equal mass black holes, or the larger of the two spins (which covers the
5048  * extreme mass case). If the result is larger than a maximum realistic
5049  * black hole spin, truncate at this maximum value.
5050  * @param S1z The z-component of the dimensionless spin of body 1.
5051  * @param S2z The z-component of the dimensionless spin of body 2.
5052  * @return Upper bound on final black hole dimensionless spin.
5053  * @see Tichy and Marronetti, Physical Review D 78 081501 (2008).
5054  * @todo It has been suggested that Barausse, Rezzolla (arXiv: 0904.2577) is
5055  * more accurate
5056  */
5058 {
5059  const double maximum_black_hole_spin = 0.998;
5060  double s;
5061  /* lower bound on the final plunge, merger, and ringdown time here the
5062  * final black hole spin is overestimated by using the formula in Tichy and
5063  * Marronetti, Physical Review D 78 081501 (2008), Eq. (1) and Table 1, for
5064  * equal mass black holes, or the larger of the two spins (which covers the
5065  * extreme mass case) */
5066  /* TODO: it has been suggested that Barausse, Rezzolla (arXiv: 0904.2577)
5067  * is more accurate */
5068  s = 0.686 + 0.15 * (S1z + S2z);
5069  if (s < fabs(S1z))
5070  s = fabs(S1z);
5071  if (s < fabs(S2z))
5072  s = fabs(S2z);
5073  /* it is possible that |S1z| or |S2z| >= 1, but s must be less than 1
5074  * (0th law of thermodynamics) so provide a maximum value for s */
5075  if (s > maximum_black_hole_spin)
5076  s = maximum_black_hole_spin;
5077  return s;
5078 }
5079 
5080 /**
5081  * @brief Routine to compute an underestimate of the starting frequency for a given chirp time.
5082  * @details
5083  * This routine estimates a start frequency for a binary inspiral from which the
5084  * actual inspiral chirp time will be shorter than the specified chirp time.
5085  * To obtain this estimate, only the leading order Newtonian coefficient is used.
5086  * The frequency returned by this routine is guaranteed to be less than the frequency
5087  * passed to XLALSimInspiralChirpTimeBound() if the returned value of that routine
5088  * is passed to this routine as tchirp.
5089  * @param tchirp The chirp time of post-Newtonian inspiral s.
5090  * @param m1 The mass of the first component in kg.
5091  * @param m2 The mass of the second component in kg.
5092  * @return Lower bound on the starting frequency of a post-Newtonian inspiral in Hz.
5093  */
5095 {
5096  double M = m1 + m2; // total mass
5097  double mu = m1 * m2 / M; // reduced mass
5098  double eta = mu / M; // symmetric mass ratio
5100  return c0 * pow(5.0 * M * (LAL_MTSUN_SI / LAL_MSUN_SI) / (eta * tchirp), 3.0 / 8.0);
5101 }
5102 
5103 /**
5104  * Function that gives the value of the desired frequency given some physical parameters
5105  *
5106  */
5108  REAL8 m1, /**< mass of companion 1 (kg) */
5109  REAL8 m2, /**< mass of companion 2 (kg) */
5110  const REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
5111  const REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
5112  const REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
5113  const REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
5114  const REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
5115  const REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
5116  FrequencyFunction freqFunc /**< name of the function to use */
5117  )
5118 {
5119 
5120  double freq; /* The return value */
5121 
5122  /* Variables needed for fIMRPhenom(x) */
5123  double chi;
5124  double m1Msun = m1 / LAL_MSUN_SI;
5125  double m2Msun = m2 / LAL_MSUN_SI;
5126 
5127  /* Variables needed for f(S)EOBNRv(x) */
5128  UINT4 SpinAlignedEOBVersion;
5130  REAL8 spin1[3];
5131  REAL8 spin2[3];
5132  int modeL;
5133  int modeM;
5134  COMPLEX16Vector modefreqVec;
5135  COMPLEX16 modeFreq;
5136 
5137  switch (freqFunc)
5138  {
5139  case fSchwarzISCO:
5140  /* Schwarzschild ISCO */
5141  freq = pow(LAL_C_SI,3) / (pow(6.,3./2.)*LAL_PI*(m1+m2)*LAL_G_SI);
5142  break;
5143  case fIMRPhenomAFinal:
5144  freq = XLALSimIMRPhenomAGetFinalFreq(m1Msun, m2Msun);
5145  break;
5146  case fIMRPhenomBFinal:
5147  chi = XLALSimIMRPhenomBComputeChi(m1Msun, m2Msun, S1z, S2z);
5148  freq = XLALSimIMRPhenomBGetFinalFreq(m1Msun, m2Msun, chi);
5149  break;
5150  case fIMRPhenomCFinal:
5151  chi = XLALSimIMRPhenomBComputeChi(m1Msun, m2Msun, S1z, S2z);
5152  freq = XLALSimIMRPhenomCGetFinalFreq(m1Msun, m2Msun, chi);
5153  break;
5154  case fIMRPhenomDPeak:
5155  freq = XLALIMRPhenomDGetPeakFreq(m1Msun, m2Msun, S1z, S2z);
5156  break;
5157 
5158  /* EOBNR ringdown frequencies all come from the same code,
5159  * just with different inputs */
5160  case fEOBNRv2HMRD:
5161  case fEOBNRv2RD:
5162  case fSEOBNRv1RD:
5163  case fSEOBNRv2RD:
5164  case fSEOBNRv4RD:
5165  // FIXME: Probably shouldn't hard code the modes.
5166  if ( freqFunc == fEOBNRv2HMRD )
5167  {
5168  modeL = 5;
5169  modeM = 5;
5171  }
5172  else
5173  {
5174  modeL = 2;
5175  modeM = 2;
5176  if (freqFunc == fEOBNRv2RD) approximant = EOBNRv2;
5177  if (freqFunc == fSEOBNRv1RD) approximant = SEOBNRv1;
5178  if (freqFunc == fSEOBNRv2RD) approximant = SEOBNRv2;
5179  if (freqFunc == fSEOBNRv4RD) approximant = SEOBNRv4;
5180  }
5181  if ( freqFunc == fEOBNRv2RD || freqFunc == fEOBNRv2HMRD )
5182  {
5183  /* Check that spins are zero */
5184  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5185  {
5186  XLALPrintError("Non-zero spins were given, but EOBNRv2 ringdown frequencies do not depend on spin.\n");
5188  spin1[0] = 0.; spin1[1] = 0.; spin1[2] = 0.;
5189  spin2[0] = 0.; spin2[1] = 0.; spin2[2] = 0.;
5190  }
5191  }
5192  else
5193  {
5194  spin1[0] = S1x; spin1[1] = S1y; spin1[2] = S1z;
5195  spin2[0] = S2x; spin2[1] = S2y; spin2[2] = S2z;
5196  }
5197 
5198  modefreqVec.length = 1;
5199  modefreqVec.data = &modeFreq;
5200  if ( XLALSimIMREOBGenerateQNMFreqV2( &modefreqVec, m1Msun, m2Msun, spin1, spin2, modeL, modeM, 1, approximant) != XLAL_SUCCESS )
5201  {
5203  }
5204 
5205  freq = creal(modeFreq) / (2 * LAL_PI);
5206  break;
5207 
5208  case fSEOBNRv5RD:
5209  modeL = 2;
5210  modeM = 2;
5212  spin1[0] = S1x; spin1[1] = S1y; spin1[2] = S1z;
5213  spin2[0] = S2x; spin2[1] = S2y; spin2[2] = S2z;
5214  modefreqVec.length = 1;
5215  modefreqVec.data = &modeFreq;
5216  if ( XLALSimIMREOBGenerateQNMFreqV5( &modefreqVec, m1Msun, m2Msun, spin1, spin2, modeL, modeM, 1, approximant) != XLAL_SUCCESS )
5217  {
5219  }
5220 
5221  freq = creal(modeFreq) / (2 * LAL_PI);
5222  break;
5223 
5224  case fSEOBNRv1Peak:
5225  case fSEOBNRv2Peak:
5226  case fSEOBNRv4Peak:
5227  case fSEOBNRv5Peak:
5228  if ( freqFunc == fSEOBNRv1Peak ) SpinAlignedEOBVersion = 1;
5229  if ( freqFunc == fSEOBNRv2Peak ) SpinAlignedEOBVersion = 2;
5230  if ( freqFunc == fSEOBNRv4Peak ) SpinAlignedEOBVersion = 4;
5231  if ( freqFunc == fSEOBNRv5Peak ) SpinAlignedEOBVersion = 5;
5232  freq = XLALSimIMRSpinAlignedEOBPeakFrequency(m1, m2, S1z, S2z,
5233  SpinAlignedEOBVersion);
5234  break;
5235  case fTEOBResumSFinal: // MA: Replace with TEOB-related RD frequency!
5236  // CAUTION: different function for BNS/NSBH/BBH cases?
5237  fprintf(stdout, "Final frequency for TEOBResumS not implemented yet.\n");
5238  freq = XLALSimIMRSpinAlignedEOBPeakFrequency(m1, m2, S1z, S2z, 2);
5239  break;
5240  default:
5241  XLALPrintError("Unsupported approximant\n");
5243  }
5244 
5245  return freq;
5246 }
5247 
5248 
5249 /**
5250  * Function that gives the default ending frequencies of the given approximant.
5251  *
5252  */
5254  REAL8 m1, /**< mass of companion 1 (kg) */
5255  REAL8 m2, /**< mass of companion 2 (kg) */
5256  const REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
5257  const REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
5258  const REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
5259  const REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
5260  const REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
5261  const REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
5262  Approximant approximant /**< post-Newtonian approximant to use for waveform production */
5263  )
5264 {
5265  FrequencyFunction freqFunc;
5266 
5267  /* input conditions */
5268  switch (approximant)
5269  {
5270  case EccentricTD:
5271  case EccentricFD:
5272  case EOBNRv2HM:
5273  case EOBNRv2:
5274  case IMRPhenomA:
5275  /* Check that spins are zero */
5276  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5277  {
5278  XLALPrintError("Non-zero spins were given, but this is a non-spinning approximant.\n");
5280  }
5281  break;
5282 
5283  case TaylorF2RedSpinTidal:
5284  case SEOBNRv1:
5285  case SEOBNRv2:
5286  case SEOBNRv2_opt:
5287  case SEOBNRv4:
5288  case SEOBNRv4_opt:
5289  case IMRPhenomB:
5290  case IMRPhenomC:
5291  case TEOBResumS:
5292  /* Check that the transverse spins are zero */
5293  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
5294  {
5295  XLALPrintError("Non-zero transverse spins were given, but this is a non-precessing approximant.\n");
5297  }
5298  break;
5299 
5300  default:
5301  break;
5302  }
5303 
5304  /* select the frequency function that is associated with each approximant */
5305  switch (approximant)
5306  {
5307  /* non-spinning inspiral-only models */
5308  // CHECKME: do they really all use Schwarzschild ISCO? */
5309  case TaylorEt:
5310  case TaylorT1:
5311  case TaylorT2:
5312  case TaylorT3:
5313  case TaylorT4:
5314  case EccentricTD:
5315  case EccentricFD:
5316  case TaylorF2:
5317  case TaylorF2Ecc:
5318  case TaylorF2NLTides:
5319  case TaylorF2RedSpin:
5320  case TaylorF2RedSpinTidal:
5321  /* Schwarzschild ISCO */
5322  freqFunc = fSchwarzISCO;
5323  break;
5324 
5325  /* IMR models */
5326  case EOBNRv2HM:
5327  freqFunc = fEOBNRv2HMRD;
5328  break;
5329 
5330  case EOBNRv2:
5331  freqFunc = fEOBNRv2RD;
5332  break;
5333 
5334  case SEOBNRv1:
5335  freqFunc = fSEOBNRv1RD;
5336  break;
5337 
5338  case SEOBNRv2:
5339  case SEOBNRv2_opt:
5340  freqFunc = fSEOBNRv2RD;
5341  break;
5342 
5343  case SEOBNRv4:
5344  case SEOBNRv4_opt:
5345  freqFunc = fSEOBNRv4RD;
5346  break;
5347 
5348  case SEOBNRv5_ROM:
5349  freqFunc = fSEOBNRv5RD;
5350  break;
5351 
5352  case IMRPhenomA:
5353  freqFunc = fIMRPhenomAFinal;
5354  break;
5355 
5356  case IMRPhenomB:
5357  freqFunc = fIMRPhenomBFinal;
5358  break;
5359 
5360  case IMRPhenomC:
5361  freqFunc = fIMRPhenomCFinal;
5362  break;
5363 
5364  case TEOBResumS:
5365  freqFunc = fTEOBResumSFinal;
5366  break;
5367 
5368  // FIXME: Following I don't know how to calculate */
5369  /* Spinning inspiral-only time domain */
5370  case SpinTaylorT5:
5371  case SpinTaylorT4:
5372  case SpinTaylorT1:
5373  case PhenSpinTaylor:
5374  /* Spinning with ringdown attachment */
5375  case PhenSpinTaylorRD:
5376  /* Spinning inspiral-only frequency domain */
5377  case SpinTaylorF2:
5378  /* NR waveforms */
5379  case NR_hdf5:
5380  case NRSur4d2s:
5381  XLALPrintError("I don't know how to calculate final freq. for this approximant, sorry!\n");
5383  break;
5384 
5385  default:
5386  XLALPrintError("Unsupported approximant\n");
5388  }
5389 
5390  return XLALSimInspiralGetFrequency(m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, freqFunc);
5391 }
5392 
5393 /** @} */
5394 
5395 /**
5396  * @name Waveform Conditioning Helper Routines
5397  * @{
5398  */
5399 
5400 /**
5401  * @brief First stage of conditioning of time-domain waveforms.
5402  * @details
5403  * The conditioning of time-domain waveforms is done in two stages:
5404  *
5405  * 1. Take a waveform that is generated so that begins a time at least textra
5406  * before it reaches f_min and apply a taper over this duration textra; follow
5407  * this up by high-pass filtering the data at frequency f_min; finally, if the
5408  * original waveform was zero-padded, strip off this padding.
5409  *
5410  * 2. The high-pass filtered waveform might have transients remaining at the
5411  * beginning and at the end; furthermore, the waveform might end at a non-zero
5412  * value (especially for non-IMR waveforms). The second stage tapers one
5413  * cycle at f_min from the beginning of the waveform and one cycle at f_max
5414  * from the end of the waveform. There is a minimum number of samples that
5415  * will be used in the tapering and if the waveform is shorter than twice
5416  * this minimum number then no Stage 2 conditioning is done.
5417  *
5418  * This routine performs Stage 1 conditioning. This stage is only performed
5419  * for waveforms originally produced in the time domain. (Frequency domain
5420  * waveforms that have been transformed into the time domain have a different
5421  * Stage 1 conditioning.)
5422  *
5423  * @param hplus Pointer to the plus-polarization timeseries.
5424  * @param hcross Pointer to the cross-polarization timeseries.
5425  * @param textra Extra time at beginning of waveform to taper (s).
5426  * @param f_min Minimum frequency for high-pass filtering (Hz).
5427  * @retval 0 Success.
5428  * @retval <0 Failure.
5429  */
5431 {
5432  size_t nzeros;
5433  size_t ntaper;
5434  size_t j;
5435 
5436  /* some generators zero-pad the end of the waveform: will remove this */
5437  nzeros = 0;
5438  while (hplus->data->data[hplus->data->length - nzeros - 1] == 0.0 && hcross->data->data[hcross->data->length - nzeros - 1] == 0.0)
5439  ++nzeros;
5440 
5441  /* apply tapers over the extra duration at the beginning */
5442  ntaper = round(textra / hplus->deltaT);
5443  for (j = 0; j < ntaper; ++j) {
5444  double w = 0.5 - 0.5 * cos(j * LAL_PI / ntaper);
5445  hplus->data->data[j] *= w;
5446  hcross->data->data[j] *= w;
5447  }
5448 
5449  /* apply time domain filter at f_min */
5450  XLALHighPassREAL8TimeSeries(hplus, f_min, 0.99, 8);
5451  XLALHighPassREAL8TimeSeries(hcross, f_min, 0.99, 8);
5452 
5453  /* now take off the zero padded end */
5454  if (nzeros) {
5455  XLALShrinkREAL8TimeSeries(hplus, 0, hplus->data->length - nzeros);
5456  XLALShrinkREAL8TimeSeries(hcross, 0, hcross->data->length - nzeros);
5457  }
5458 
5459  return 0;
5460 }
5461 
5462 /**
5463  * @brief Second stage of conditioning of time-domain waveforms.
5464  * @details
5465  * The conditioning of time-domain waveforms is done in two stages:
5466  *
5467  * 1. Take a waveform that is generated so that begins a time at least textra
5468  * before it reaches f_min and apply a taper over this duration textra; follow
5469  * this up by high-pass filtering the data at frequency f_min; finally, if the
5470  * original waveform was zero-padded, strip off this padding.
5471  *
5472  * 2. The high-pass filtered waveform might have transients remaining at the
5473  * beginning and at the end; furthermore, the waveform might end at a non-zero
5474  * value (especially for non-IMR waveforms). The second stage tapers one
5475  * cycle at f_min from the beginning of the waveform and one cycle at f_max
5476  * from the end of the waveform. There is a minimum number of samples that
5477  * will be used in the tapering and if the waveform is shorter than twice
5478  * this minimum number then no Stage 2 conditioning is done.
5479  *
5480  * This routine performs Stage 2 conditioning. This stage is performed both
5481  * for waveforms originally produced in the time domain, and for waveforms that
5482  * were originally produced in the frequency domain and then transformed to
5483  * the time domain. This stage follows some form of Stage 1 conditioning,
5484  * which is different depending on whether the original waveform was generated
5485  * in the time domain or in the frequency domain.
5486  *
5487  * @param hplus Pointer to the plus-polarization timeseries.
5488  * @param hcross Pointer to the cross-polarization timeseries.
5489  * @param f_min Minimum frequency for tapering at the start (Hz).
5490  * @param f_max Minimum frequency for tapering at the end (Hz).
5491  * @retval 0 Success.
5492  * @retval <0 Failure.
5493  */
5495 {
5496  const size_t min_taper_samples = 4;
5497  size_t ntaper;
5498  size_t j;
5499 
5500  /* final tapering at the beginning and at the end */
5501  /* if this waveform is shorter than 2*min_taper_samples, do nothing */
5502  if (hplus->data->length < 2 * min_taper_samples) {
5503  XLAL_PRINT_WARNING("waveform is too shorter than %zu samples: no final tapering applied", 2 * min_taper_samples);
5504  return 0;
5505  }
5506 
5507  /* taper end of waveform: 1 cycle at f_max; at least min_taper_samples
5508  * note: this tapering is done so the waveform goes to zero at the next
5509  * point beyond the end of the data */
5510  ntaper = round(1.0 / (f_max * hplus->deltaT));
5511  if (ntaper < min_taper_samples)
5512  ntaper = min_taper_samples;
5513  for (j = 1; j < ntaper; ++j) {
5514  double w = 0.5 - 0.5 * cos(j * LAL_PI / ntaper);
5515  hplus->data->data[hplus->data->length - j] *= w;
5516  hcross->data->data[hcross->data->length - j] *= w;
5517  }
5518 
5519  /* there could be a filter transient at the beginning too: we should have
5520  * some safety there owing to the fact that we are starting at a lower
5521  * frequency than is needed, so taper off one cycle at the low frequency */
5522  ntaper = round(1.0 / (f_min * hplus->deltaT));
5523  if (ntaper < min_taper_samples)
5524  ntaper = min_taper_samples;
5525  for (j = 0; j < ntaper; ++j) {
5526  double w = 0.5 - 0.5 * cos(j * LAL_PI / ntaper);
5527  hplus->data->data[j] *= w;
5528  hcross->data->data[j] *= w;
5529  }
5530 
5531  return 0;
5532 }
5533 
5534 
5535 /**
5536  * @brief Function for determining the starting frequency
5537  * of the (2,2) mode when the highest order contribution starts at fLow.
5538  * @details
5539  * Compute the minimum frequency for waveform generation
5540  * using amplitude orders above Newtonian. The waveform
5541  * generator turns on all orders at the orbital
5542  * associated with fMin, so information from higher
5543  * orders is not included at fLow unless fMin is
5544  * sufficiently low.
5545  *
5546  * @param fLow Requested lower frequency.
5547  * @param ampOrder Requested amplitude order.
5548  * @param approximant LALApproximant
5549  * @retval fStart The lower frequency to use to include corrections.
5550  */
5552 {
5553  if (ampOrder == -1) {
5555  ampOrder = MAX_PRECESSING_AMP_PN_ORDER;
5556  else
5557  ampOrder = MAX_NONPRECESSING_AMP_PN_ORDER;
5558  }
5559 
5560  REAL8 fStart;
5561  fStart = fLow * 2./(ampOrder+2);
5562  return fStart;
5563 }
5564 
5565 /**
5566  * @deprecated Use XLALSimInspiralChooseTDWaveform() instead
5567  * Chooses between different approximants when requesting a waveform to be generated
5568  * For spinning waveforms, all known spin effects up to given PN order are included
5569  * Returns the waveform in the time domain.
5570  *
5571  * The parameters passed must be in SI units.
5572  */
5574  REAL8TimeSeries **hplus, /**< +-polarization waveform */
5575  REAL8TimeSeries **hcross, /**< x-polarization waveform */
5576  const REAL8 m1, /**< mass of companion 1 (kg) */
5577  const REAL8 m2, /**< mass of companion 2 (kg) */
5578  const REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
5579  const REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
5580  const REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
5581  const REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
5582  const REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
5583  const REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
5584  const REAL8 distance, /**< distance of source (m) */
5585  const REAL8 inclination, /**< inclination of source (rad) */
5586  const REAL8 phiRef, /**< reference orbital phase (rad) */
5587  const REAL8 longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
5588  const REAL8 eccentricity, /**< eccentrocity at reference epoch */
5589  const REAL8 UNUSED meanPerAno, /**< mean anomaly of periastron */
5590  // frequency sampling parameters, no default value
5591  const REAL8 deltaT, /**< sampling interval (s) */
5592  const REAL8 f_min, /**< starting GW frequency (Hz) */
5593  REAL8 f_ref, /**< reference GW frequency (Hz) */
5594  const REAL8 lambda1, /**< (tidal deformability of mass 1) / m1^5 (dimensionless) */
5595  const REAL8 lambda2, /**< (tidal deformability of mass 2) / m2^5 (dimensionless) */
5596  const REAL8 dQuadParam1, /**< (quad-monop parameter of mass 1) / m1^5 -1 (dimensionless), give 0 for BHs */
5597  const REAL8 dQuadParam2, /**< (quad-monop parameter of mass 2) / m2^5 -1 (dimensionless), give 0 for BHs */
5598  LALSimInspiralWaveformFlags *waveFlags, /**< Set of flags to control special behavior of some waveform families. Pass in NULL (or None in python) for default flags */
5599  LALSimInspiralTestGRParam *nonGRparams, /**< Linked list of non-GR parameters. Pass in NULL (or None in python) for standard GR waveforms */
5600  int amplitudeO, /**< twice post-Newtonian amplitude order */
5601  const int phaseO, /**< twice post-Newtonian order */
5602  const Approximant approximant /**< post-Newtonian approximant to use for waveform production */
5603  )
5604 {
5605  LALDict *LALparams = NULL;
5606  REAL8 LNhatx, LNhaty, LNhatz, E1x, E1y, E1z;
5607  char *numrel_data_path;
5608  //REAL8 tmp1, tmp2;
5609  int ret;
5610  /* N.B. the quadrupole of a spinning compact body labeled by A is
5611  * Q_A = - quadparam_A chi_A^2 m_A^3 (see gr-qc/9709032)
5612  * where quadparam = 1 for BH ~= 4-8 for NS.
5613  * This affects the quadrupole-monopole interaction.
5614  */
5615  REAL8 v0 = 1., quadparam1 = 1.+dQuadParam1, quadparam2 = 1.+dQuadParam2;
5616 
5617  /* General sanity checks that will abort
5618  *
5619  * If non-GR approximants are added, include them in
5620  * XLALSimInspiralApproximantAcceptTestGRParams()
5621  */
5623  {
5624  XLALPrintError("XLAL Error - %s: Passed in non-NULL pointer to LALSimInspiralTestGRParam for an approximant that does not use LALSimInspiralTestGRParam\n", __func__);
5626  }
5627 
5628  /* Support variables for precessing wfs*/
5629  REAL8 incl;
5630 
5631  UINT4 PrecEOBversion;
5632 
5633  /* SEOBNR flag for model version. 1 for SEOBNRv1, 2 for SEOBNRv2 */
5634  UINT4 SpinAlignedEOBversion;
5635  REAL8 spin1x,spin1y,spin1z;
5636  REAL8 spin2x,spin2y,spin2z;
5637  REAL8 polariz=longAscNodes;
5638  //LIGOTimeGPS epoch = LIGOTIMEGPSZERO;
5639 
5640  /* General sanity check the input parameters - only give warnings! */
5641  if( deltaT > 1. )
5642  XLALPrintWarning("XLAL Warning - %s: Large value of deltaT = %e requested.\nPerhaps sample rate and time step size were swapped?\n", __func__, deltaT);
5643  if( deltaT < 1./16385. )
5644  XLALPrintWarning("XLAL Warning - %s: Small value of deltaT = %e requested.\nCheck for errors, this could create very large time series.\n", __func__, deltaT);
5645  if( m1 < 0.09 * LAL_MSUN_SI )
5646  XLALPrintWarning("XLAL Warning - %s: Small value of m1 = %e (kg) = %e (Msun) requested.\nPerhaps you have a unit conversion error?\n", __func__, m1, m1/LAL_MSUN_SI);
5647  if( m2 < 0.09 * LAL_MSUN_SI )
5648  XLALPrintWarning("XLAL Warning - %s: Small value of m2 = %e (kg) = %e (Msun) requested.\nPerhaps you have a unit conversion error?\n", __func__, m2, m2/LAL_MSUN_SI);
5649  if( m1 + m2 > 1000. * LAL_MSUN_SI )
5650  XLALPrintWarning("XLAL Warning - %s: Large value of total mass m1+m2 = %e (kg) = %e (Msun) requested.\nSignal not likely to be in band of ground-based detectors.\n", __func__, m1+m2, (m1+m2)/LAL_MSUN_SI);
5651  if( S1x*S1x + S1y*S1y + S1z*S1z > 1.000001 )
5652  XLALPrintWarning("XLAL Warning - %s: S1 = (%e,%e,%e) with norm > 1 requested.\nAre you sure you want to violate the Kerr bound?\n", __func__, S1x, S1y, S1z);
5653  if( S2x*S2x + S2y*S2y + S2z*S2z > 1.000001 )
5654  XLALPrintWarning("XLAL Warning - %s: S2 = (%e,%e,%e) with norm > 1 requested.\nAre you sure you want to violate the Kerr bound?\n", __func__, S2x, S2y, S2z);
5655  if( f_min < 1. )
5656  XLALPrintWarning("XLAL Warning - %s: Small value of fmin = %e requested.\nCheck for errors, this could create a very long waveform.\n", __func__, f_min);
5657  if( f_min > 40.000001 )
5658  XLALPrintWarning("XLAL Warning - %s: Large value of fmin = %e requested.\nCheck for errors, the signal will start in band.\n", __func__, f_min);
5659 
5660  /* adjust the reference frequency for certain precessing approximants:
5661  * if that approximate interprets f_ref==0 to be f_min, set f_ref=f_min;
5662  * otherwise do nothing */
5664 
5665  switch (approximant)
5666  {
5667  /* non-spinning inspiral-only models */
5668  case TaylorEt:
5669  /* Waveform-specific sanity checks */
5671  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
5672  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5673  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
5674  if( !checkTidesZero(lambda1, lambda2) )
5675  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
5676  if( f_ref != 0.)
5677  XLALPrintWarning("XLAL Warning - %s: This approximant does use f_ref. The reference phase will be defined at coalescence.\n", __func__);
5678  /* Call the waveform driver routine */
5679  ret = XLALSimInspiralTaylorEtPNGenerator(hplus, hcross, phiRef, v0,
5680  deltaT, m1, m2, f_min, distance, inclination, amplitudeO, phaseO);
5681  break;
5682 
5683  case TaylorT1:
5684  /* Waveform-specific sanity checks */
5686  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
5688  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
5690  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralSpinOrder provided, but this approximant does not use that flag.");
5691  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5692  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
5693  /* Call the waveform driver routine */
5694  ret = XLALSimInspiralTaylorT1PNGenerator(hplus, hcross, phiRef, v0,
5695  deltaT, m1, m2, f_min, f_ref, distance, inclination, lambda1, lambda2,
5696  0, amplitudeO, phaseO);
5697  break;
5698 
5699  case TaylorT2:
5700  /* Waveform-specific sanity checks */
5702  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
5704  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
5706  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralSpinOrder provided, but this approximant does not use that flag.");
5707  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5708  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
5709  /* Call the waveform driver routine */
5710  ret = XLALSimInspiralTaylorT2PNGenerator(hplus, hcross, phiRef, v0,
5711  deltaT, m1, m2, f_min, f_ref, distance, inclination, lambda1, lambda2,
5712  0, amplitudeO, phaseO);
5713  break;
5714 
5715  case TaylorT3:
5716  /* Waveform-specific sanity checks */
5718  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
5720  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
5722  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralSpinOrder provided, but this approximant does not use that flag.");
5723  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5724  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
5725  /* Call the waveform driver routine */
5726  ret = XLALSimInspiralTaylorT3PNGenerator(hplus, hcross, phiRef, v0,
5727  deltaT, m1, m2, f_min, f_ref, distance, inclination, lambda1, lambda2,
5728  0, amplitudeO, phaseO);
5729  break;
5730 
5731  case TaylorT4:
5732  /* Waveform-specific sanity checks */
5734  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
5736  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
5738  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralSpinOrder provided, but this approximant does not use that flag.");
5739  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5740  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
5741  /* Call the waveform driver routine */
5742  ret = XLALSimInspiralTaylorT4PNGenerator(hplus, hcross, phiRef, v0,
5743  deltaT, m1, m2, f_min, f_ref, distance, inclination, lambda1, lambda2,
5744  0, amplitudeO, phaseO);
5745  break;
5746 
5747  case EccentricTD:
5748  /* Waveform-specific sanity checks */
5750  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
5752  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
5754  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralSpinOrder provided, but this approximant does not use that flag.");
5755  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5756  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
5757  if( !checkTidesZero(lambda1, lambda2) )
5758  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
5759  /* Call the waveform driver routine */
5760  ret = XLALSimInspiralEccentricTDPNGenerator(hplus, hcross, phiRef,
5761  deltaT, m1, m2, f_min, f_ref, distance, inclination, eccentricity,
5762  amplitudeO, phaseO);
5763  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
5764  break;
5765 
5766  /* non-spinning inspiral-merger-ringdown models */
5767  case IMRPhenomA:
5768  /* Waveform-specific sanity checks */
5770  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
5771  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5772  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
5773  if( !checkTidesZero(lambda1, lambda2) )
5774  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
5775  if( f_ref != 0.)
5776  XLALPrintWarning("XLAL Warning - %s: This approximant does use f_ref. The reference phase will be defined at coalescence.\n", __func__);
5777  /* Call the waveform driver routine */
5778  // NB: f_max = 0 will generate up to the ringdown cut-off frequency
5779  ret = XLALSimIMRPhenomAGenerateTD(hplus, hcross, phiRef, deltaT,
5780  m1, m2, f_min, 0., distance, inclination);
5781  break;
5782 
5783  case EOBNRv2HM:
5784  /* Waveform-specific sanity checks */
5786  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
5787  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5788  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
5789  if( !checkTidesZero(lambda1, lambda2) )
5790  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
5791  if( f_ref != 0.)
5792  XLALPrintWarning("XLAL Warning - %s: This approximant does use f_ref. The reference phase will be defined at coalescence.\n", __func__);
5793  /* Call the waveform driver routine */
5794  // FIXME: need to create a function to take in different modes or produce an error if all modes not given
5795  ret = XLALSimIMREOBNRv2AllModes(hplus, hcross, phiRef, deltaT,
5796  m1, m2, f_min, distance, inclination);
5797  break;
5798 
5799  case EOBNRv2:
5800  /* Waveform-specific sanity checks */
5802  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
5803  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
5804  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
5805  if( !checkTidesZero(lambda1, lambda2) )
5806  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
5807  if( f_ref != 0.)
5808  XLALPrintWarning("XLAL Warning - %s: This approximant does use f_ref. The reference phase will be defined at coalescence.\n", __func__);
5809  /* Call the waveform driver routine */
5810  ret = XLALSimIMREOBNRv2DominantMode(hplus, hcross, phiRef, deltaT,
5811  m1, m2, f_min, distance, inclination);
5812  break;
5813 
5814  /* spinning inspiral-only models */
5815  case SpinTaylorT5:
5816  /* Waveform-specific sanity checks */
5817  /* Sanity check unused fields of waveFlags */
5818  XLALSimInspiralInitialConditionsPrecessingApproxs(&incl,&spin1x,&spin1y,&spin1z,&spin2x,&spin2y,&spin2z,inclination,S1x,S1y,S1z,S2x,S2y,S2z,m1,m2,f_ref,phiRef,XLALSimInspiralGetFrameAxis(waveFlags));
5819  LNhatx = sin(incl);
5820  LNhaty = 0.;
5821  LNhatz = cos(incl);
5822  E1x = 0.;
5823  E1y = 1.;
5824  E1z = 0.;
5825  polariz+=LAL_PI/2.;
5826  /* Maximum PN amplitude order for precessing waveforms is
5827  * MAX_PRECESSING_AMP_PN_ORDER */
5828  amplitudeO = amplitudeO <= MAX_PRECESSING_AMP_PN_ORDER ?
5829  amplitudeO : MAX_PRECESSING_AMP_PN_ORDER;
5830  /* Call the waveform driver routine */
5831  ret = XLALSimInspiralSpinTaylorT5(hplus, hcross, phiRef, deltaT,
5832  m1, m2, f_min, f_ref, distance, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z,
5833  LNhatx, LNhaty, LNhatz, E1x, E1y, E1z, NULL);
5834  break;
5835 
5836  // need to make a consistent choice for SpinTaylorT4 and PSpinInspiralRD waveform inputs
5837  // proposal: TotalJ frame of PSpinInspiralRD
5838  // inclination denotes the angle between the view direction
5839  // and J (J is constant during the evolution, J//z, both N and initial
5840  // L are in the x-z plane) and the spin coordinates are given wrt
5841  // initial ** L **.
5842  case SpinTaylorT4:
5843  /* Waveform-specific sanity checks */
5844  /* Sanity check unused fields of waveFlags */
5845  XLALSimInspiralInitialConditionsPrecessingApproxs(&incl,&spin1x,&spin1y,&spin1z,&spin2x,&spin2y,&spin2z,inclination,S1x,S1y,S1z,S2x,S2y,S2z,m1,m2,f_ref,phiRef,XLALSimInspiralGetFrameAxis(waveFlags));
5846  LNhatx = sin(incl);
5847  LNhaty = 0.;
5848  LNhatz = cos(incl);
5849  E1x = 0.;
5850  E1y = 1.;
5851  E1z = 0.;
5852  polariz+=LAL_PI/2.;
5853  /* Maximum PN amplitude order for precessing waveforms is
5854  * MAX_PRECESSING_AMP_PN_ORDER */
5855  amplitudeO = amplitudeO <= MAX_PRECESSING_AMP_PN_ORDER ?
5856  amplitudeO : MAX_PRECESSING_AMP_PN_ORDER;
5857  /* Call the waveform driver routine */
5858  ret = XLALSimInspiralSpinTaylorT4OLD(hplus, hcross, phiRef, 1.,deltaT,
5859  m1, m2, f_min, f_ref, distance, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z,
5860  LNhatx, LNhaty, LNhatz, E1x, E1y, E1z, lambda1, lambda2,
5861  quadparam1, quadparam2, NULL,
5862  phaseO, amplitudeO);
5863  break;
5864 
5865  case SpinTaylorT1:
5866  /* Waveform-specific sanity checks */
5867  /* Sanity check unused fields of waveFlags */
5868  XLALSimInspiralInitialConditionsPrecessingApproxs(&incl,&spin1x,&spin1y,&spin1z,&spin2x,&spin2y,&spin2z,inclination,S1x,S1y,S1z,S2x,S2y,S2z,m1,m2,f_ref,phiRef,XLALSimInspiralGetFrameAxis(waveFlags));
5869  LNhatx = sin(incl);
5870  LNhaty = 0.;
5871  LNhatz = cos(incl);
5872  E1x = 0.;
5873  E1y = 1.;
5874  E1z = 0.;
5875  polariz+=LAL_PI/2.;
5876  /* Maximum PN amplitude order for precessing waveforms is
5877  * MAX_PRECESSING_AMP_PN_ORDER */
5878  amplitudeO = amplitudeO <= MAX_PRECESSING_AMP_PN_ORDER ?
5879  amplitudeO : MAX_PRECESSING_AMP_PN_ORDER;
5880  /* Call the waveform driver routine */
5881  ret = XLALSimInspiralSpinTaylorT1OLD(hplus, hcross, phiRef, 1., deltaT,
5882  m1, m2, f_min, f_ref, distance, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z, LNhatx, LNhaty, LNhatz, E1x, E1y, E1z, lambda1, lambda2,
5883  quadparam1, quadparam2, NULL,
5884  phaseO, amplitudeO);
5885  break;
5886 
5887  case SpinDominatedWf:
5888  // waveform specific sanity checks
5889  if (S2x != 0. || S2y != 0. || S2z != 0.){
5890  XLALPrintError("XLAL Error : The spindominatedwf approximant is only for 1 spin case.\n");
5892  }
5893  /*Maximal PN amplitude order is 1.5, maximal phase order is 2 PN*/
5894  if (amplitudeO > 3) {
5895  XLALPrintError("XLAL Error : Foe the spindominatedwf approximant maximal amplitude correction is 1.5 PN\n");
5897  }
5898  if (phaseO > 4){
5899  XLALPrintError("XLAL Error : For the spindominatedwf approximant maximal phase correction is 2 PN\n");
5901  }
5902  incl=inclination;
5903  LNhatx = 0.;
5904  LNhaty = 0.;
5905  LNhatz = 1.;
5906  /* Call the waveform driver routine */
5907  ret = XLALSimInspiralSpinDominatedWaveformInterfaceTD(hplus, hcross, deltaT, m1, m2, f_min, f_ref, distance, S1x, S1y, S1z, LNhatx, LNhaty, LNhatz, incl, phaseO, amplitudeO, phiRef);
5908  break;
5909 
5910  /* spin aligned inspiral-merger-ringdown models */
5911  case IMRPhenomB:
5912  /* Waveform-specific sanity checks */
5914  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
5915  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
5916  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
5917  if( !checkTidesZero(lambda1, lambda2) )
5918  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
5919  if( f_ref != 0.)
5920  XLALPrintWarning("XLAL Warning - %s: This approximant does use f_ref. The reference phase will be defined at coalescence.\n", __func__);
5921  /* Call the waveform driver routine */
5922  // NB: f_max = 0 will generate up to the ringdown cut-off frequency
5923  ret = XLALSimIMRPhenomBGenerateTD(hplus, hcross, phiRef, deltaT,
5924  m1, m2, XLALSimIMRPhenomBComputeChi(m1, m2, S1z, S2z),
5925  f_min, 0., distance, inclination);
5926  break;
5927 
5928  case PhenSpinTaylor:
5929  /* Waveform-specific sanity checks */
5930  if( !checkTidesZero(lambda1, lambda2) )
5931  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
5932  /* Call the waveform driver routine */
5933  XLALSimInspiralInitialConditionsPrecessingApproxs(&incl,&spin1x,&spin1y,&spin1z,&spin2x,&spin2y,&spin2z,inclination,S1x,S1y,S1z,S2x,S2y,S2z,m1,m2,f_ref,phiRef,XLALSimInspiralGetFrameAxis(waveFlags));
5934  polariz+=LAL_PI/2.;
5935  ret = XLALSimSpinInspiralGenerator(hplus, hcross, phiRef,
5936  deltaT, m1, m2, f_min, f_ref, distance, incl, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z,
5937  phaseO, amplitudeO, lambda1, lambda2, quadparam1, quadparam2, NULL);
5938  break;
5939 
5940  case IMRPhenomC:
5941  /* Waveform-specific sanity checks */
5943  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
5944  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
5945  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
5946  if( !checkTidesZero(lambda1, lambda2) )
5947  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
5948  if( f_ref != 0.)
5949  XLALPrintWarning("XLAL Warning - %s: This approximant does use f_ref. The reference phase will be defined at coalescence.\n", __func__);
5950  /* Call the waveform driver routine */
5951  // NB: f_max = 0 will generate up to the ringdown cut-off frequency
5952  ret = XLALSimIMRPhenomCGenerateTD(hplus, hcross, phiRef, deltaT,
5953  m1, m2, XLALSimIMRPhenomBComputeChi(m1, m2, S1z, S2z),
5954  f_min, 0., distance, inclination, NULL);
5955  break;
5956 
5957  case IMRPhenomD:
5959  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
5960  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
5961  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
5962  if( !checkTidesZero(lambda1, lambda2) )
5963  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
5964  // generate TD waveforms with zero inclincation so that amplitude can be
5965  // calculated from hplus and hcross, apply inclination-dependent factors
5966  // in loop below
5967  /* FIXME: BUSTED -- EXTRA PARAMS NOT IMPLEMENTED */
5968  ret = XLALSimInspiralTDFromFD(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, distance, 0.0, phiRef, 0.0, 0.0, 0.0, deltaT, f_min, f_ref, NULL, approximant);
5969  REAL8 maxamp=0;
5970  REAL8TimeSeries *hp = *hplus;
5971  REAL8TimeSeries *hc = *hcross;
5972  INT4 maxind=hp->data->length - 1;
5973  INT4 loopi;
5974  const REAL8 cfac=cos(inclination);
5975  const REAL8 pfac = 0.5 * (1. + cfac*cfac);
5976 
5977  for (loopi=hp->data->length - 1; loopi > -1; loopi--)
5978  {
5979  REAL8 ampsqr = (hp->data->data[loopi])*(hp->data->data[loopi]) +
5980  (hc->data->data[loopi])*(hc->data->data[loopi]);
5981  if (ampsqr > maxamp)
5982  {
5983  maxind=loopi;
5984  maxamp=ampsqr;
5985  }
5986  hp->data->data[loopi] *= pfac;
5987  hc->data->data[loopi] *= cfac;
5988  }
5989  XLALGPSSetREAL8(&(hp->epoch), (-1.) * deltaT * maxind);
5990  XLALGPSSetREAL8(&(hc->epoch), (-1.) * deltaT * maxind);
5991  break;
5992 
5993  case IMRPhenomPv2:
5994  /* FIXME: BUSTED -- EXTRA PARAMS NOT IMPLEMENTED */
5995  ret = XLALSimInspiralTDFromFD(hplus, hcross, m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, distance, inclination, phiRef, 0.0, 0.0, 0.0, deltaT, f_min, f_ref, NULL, approximant);
5996  break;
5997 
5998  case PhenSpinTaylorRD:
5999  /* Waveform-specific sanity checks */
6000  if( !checkTidesZero(lambda1, lambda2) )
6001  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6002  if( f_ref != 0.)
6003  XLALPrintWarning("XLAL Warning - %s: This approximant does use f_ref. The reference phase will be defined at the start.\n", __func__);
6004  /* Call the waveform driver routine */
6005  XLALSimInspiralInitialConditionsPrecessingApproxs(&incl,&spin1x,&spin1y,&spin1z,&spin2x,&spin2y,&spin2z,inclination,S1x,S1y,S1z,S2x,S2y,S2z,m1,m2,f_ref,phiRef,XLALSimInspiralGetFrameAxis(waveFlags));
6006  polariz+=LAL_PI/2.;
6007  ret = XLALSimIMRPhenSpinInspiralRDGenerator(hplus, hcross, phiRef,
6008  deltaT, m1, m2, f_min, f_ref, distance, incl, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z,
6009  phaseO, amplitudeO, lambda1, lambda2, quadparam1, quadparam2, NULL);
6010  break;
6011 
6012  case SEOBNRv1:
6013  /* Waveform-specific sanity checks */
6015  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6016  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6017  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6018  if( !checkTidesZero(lambda1, lambda2) )
6019  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6020  if( f_ref != 0.)
6021  XLALPrintWarning("XLAL Warning - %s: This approximant does not use f_ref. The reference phase will be defined at coalescence.\n", __func__);
6022  /* Call the waveform driver routine */
6023  SpinAlignedEOBversion = 1;
6024  ret = XLALSimIMRSpinAlignedEOBWaveform(hplus, hcross, phiRef,
6025  deltaT, m1, m2, f_min, distance, inclination, S1z, S2z, SpinAlignedEOBversion, LALparams);
6026  break;
6027 
6028  case SEOBNRv2:
6029  /* Waveform-specific sanity checks */
6031  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6032  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6033  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6034  if( !checkTidesZero(lambda1, lambda2) )
6035  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6036  if( f_ref != 0.)
6037  XLALPrintWarning("XLAL Warning - %s: This approximant does not use f_ref. The reference phase will be defined at coalescence.\n", __func__);
6038  /* Call the waveform driver routine */
6039  SpinAlignedEOBversion = 2;
6040  ret = XLALSimIMRSpinAlignedEOBWaveform(hplus, hcross, phiRef,
6041  deltaT, m1, m2, f_min, distance, inclination, S1z, S2z, SpinAlignedEOBversion, LALparams);
6042  break;
6043 
6044  case SEOBNRv4:
6045  /* Waveform-specific sanity checks */
6047  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6048  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6049  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6050  if( !checkTidesZero(lambda1, lambda2) )
6051  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6052  if( f_ref != 0.)
6053  XLALPrintWarning("XLAL Warning - %s: This approximant does not use f_ref. The reference phase will be defined at coalescence.\n", __func__);
6054  /* Call the waveform driver routine */
6055  SpinAlignedEOBversion = 4;
6056  ret = XLALSimIMRSpinAlignedEOBWaveform(hplus, hcross, phiRef,
6057  deltaT, m1, m2, f_min, distance, inclination, S1z, S2z, SpinAlignedEOBversion, LALparams);
6058  break;
6059 
6060  case SEOBNRv2_opt:
6061  /* Waveform-specific sanity checks */
6063  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6064  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6065  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6066  if( !checkTidesZero(lambda1, lambda2) )
6067  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6068  if( f_ref != 0.)
6069  XLALPrintWarning("XLAL Warning - %s: This approximant does not use f_ref. The reference phase will be defined at coalescence.\n", __func__);
6070  /* Call the waveform driver routine */
6071  SpinAlignedEOBversion = 200;
6072  ret = XLALSimIMRSpinAlignedEOBWaveform(hplus, hcross, phiRef,
6073  deltaT, m1, m2, f_min, distance, inclination, S1z, S2z, SpinAlignedEOBversion, LALparams);
6074  break;
6075 
6076  case SEOBNRv3:
6077  /* Waveform-specific sanity checks */
6079  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6080  if( !checkTidesZero(lambda1, lambda2) )
6081  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6082  if( f_ref != 0.)
6083  XLALPrintWarning("XLAL Warning - %s: This approximant does use f_ref. The reference phase will be defined at coalescence.\n", __func__);
6084  /* Call the waveform driver routine */
6085  REAL8 spin1[3], spin2[3];
6086  spin1[0] = S1x; spin1[1] = S1y; spin1[2] = S1z;
6087  spin2[0] = S2x; spin2[1] = S2y; spin2[2] = S2z;
6088  PrecEOBversion = 3;
6089  ret = XLALSimIMRSpinEOBWaveform(hplus, hcross, /*&epoch,*/ phiRef,
6090  deltaT, m1, m2, f_min, distance, inclination, spin1, spin2, PrecEOBversion);
6091  break;
6092 
6093  case SEOBNRv4_opt:
6094  /* Waveform-specific sanity checks */
6096  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6097  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6098  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6099  if( !checkTidesZero(lambda1, lambda2) )
6100  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6101  if( f_ref != 0.)
6102  XLALPrintWarning("XLAL Warning - %s: This approximant does not use f_ref. The reference phase will be defined at coalescence.\n", __func__);
6103  /* Call the waveform driver routine */
6104  SpinAlignedEOBversion = 400;
6105  ret = XLALSimIMRSpinAlignedEOBWaveform(hplus, hcross, phiRef,
6106  deltaT, m1, m2, f_min, distance, inclination, S1z, S2z, SpinAlignedEOBversion, LALparams);
6107  break;
6108 
6109  case HGimri:
6110  /* Waveform-specific sanity checks */
6111  if( !checkTidesZero(lambda1, lambda2) )
6112  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6113  if( !checkCOSpinZero(S2x, S2y, S2z) )
6114  XLAL_ERROR(XLAL_EINVAL, "Non-zero CO spin given, but this approximant does not support this case.");
6115  /* Call the waveform driver */
6116  ret = XLALHGimriGenerator(hplus, hcross, phiRef, deltaT, m1, m2, f_min, distance, inclination, S1z);
6117  break;
6118 
6119  case NR_hdf5:
6120  /* Waveform-specific sanity checks */
6121  numrel_data_path = XLALSimInspiralGetNumrelDataOLD(waveFlags);
6122  /* Call the waveform driver routine */
6123  ret = XLALSimInspiralNRWaveformGetHplusHcross(hplus, hcross,
6124  phiRef, inclination, deltaT, m1, m2, distance, f_min, f_ref, S1x, S1y, S1z,
6125  S2x, S2y, S2z, numrel_data_path, NULL);
6126  XLALFree(numrel_data_path);
6127  break;
6128 
6129 
6130  default:
6131  XLALPrintError("TD version of approximant not implemented in lalsimulation\n");
6133  }
6134 
6135  if (polariz) {
6136  REAL8 tmpP,tmpC;
6137  REAL8 cp=cos(2.*polariz);
6138  REAL8 sp=sin(2.*polariz);
6139  for (UINT4 idx=0;idx<(*hplus)->data->length;idx++) {
6140  tmpP=(*hplus)->data->data[idx];
6141  tmpC=(*hcross)->data->data[idx];
6142  (*hplus)->data->data[idx] =cp*tmpP+sp*tmpC;
6143  (*hcross)->data->data[idx]=cp*tmpC-sp*tmpP;
6144  }
6145  }
6146 
6147  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6148 
6149  return ret;
6150 }
6151 
6152 /**
6153  * @deprecated Use XLALSimInspiralChooseFDWaveform() instead
6154  * Chooses between different approximants when requesting a waveform to be generated
6155  * For spinning waveforms, all known spin effects up to given PN order are included
6156  * Returns the waveform in the frequency domain.
6157  */
6159  COMPLEX16FrequencySeries **hptilde, /**< FD plus polarization */
6160  COMPLEX16FrequencySeries **hctilde, /**< FD cross polarization */
6161  const REAL8 m1, /**< mass of companion 1 (kg) */
6162  const REAL8 m2, /**< mass of companion 2 (kg) */
6163  const REAL8 S1x, /**< x-component of the dimensionless spin of object 1 */
6164  const REAL8 S1y, /**< y-component of the dimensionless spin of object 1 */
6165  const REAL8 S1z, /**< z-component of the dimensionless spin of object 1 */
6166  const REAL8 S2x, /**< x-component of the dimensionless spin of object 2 */
6167  const REAL8 S2y, /**< y-component of the dimensionless spin of object 2 */
6168  const REAL8 S2z, /**< z-component of the dimensionless spin of object 2 */
6169  const REAL8 distance, /**< distance of source (m) */
6170  const REAL8 inclination, /**< inclination of source (rad) */
6171  const REAL8 phiRef, /**< reference orbital phase (rad) */
6172  const REAL8 longAscNodes, /**< longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation */
6173  const REAL8 eccentricity, /**< eccentricity at reference epoch */
6174  const REAL8 UNUSED meanPerAno, /**< mean anomaly of periastron */
6175  // frequency sampling parameters, no default value
6176  const REAL8 deltaF, /**< sampling interval (Hz) */
6177  const REAL8 f_min, /**< starting GW frequency (Hz) */
6178  const REAL8 f_max, /**< ending GW frequency (Hz) */
6179  REAL8 f_ref, /**< Reference frequency (Hz) */
6180  const REAL8 lambda1, /**< (tidal deformability of mass 1) / m1^5 (dimensionless) */
6181  const REAL8 lambda2, /**< (tidal deformability of mass 2) / m2^5 (dimensionless) */
6182  const REAL8 dQuadParam1, /**< (quad-monop parameter of mass 1) / m1^5 -1 (dimensionless), give 0 for BHs */
6183  const REAL8 dQuadParam2, /**< (quad-monop parameter of mass 2) / m2^5 -1 (dimensionless), give 0 for BHs */
6184  LALSimInspiralWaveformFlags *waveFlags, /**< Set of flags to control special behavior of some waveform families. Pass in NULL (or None in python) for default flags */
6185  LALSimInspiralTestGRParam *nonGRparams, /**< Linked list of non-GR parameters. Pass in NULL (or None in python) for standard GR waveforms */
6186  int amplitudeO, /**< twice post-Newtonian amplitude order */
6187  const int phaseO, /**< twice post-Newtonian order */
6188  const Approximant approximant /**< post-Newtonian approximant to use for waveform production */
6189  )
6190 {
6191  REAL8 LNhatx, LNhaty, LNhatz;
6192  REAL8 tmp1, tmp2;
6193  REAL8 E1x, E1y, E1z;
6194  REAL8 kMax;
6195  REAL8 v0, fStart;
6196  int ret;
6197  unsigned int j;
6198  REAL8 pfac, cfac;
6199  REAL8 quadparam1 = 1.+dQuadParam1, quadparam2 = 1.+dQuadParam2;
6200  INT4 phiRefAtEnd;
6201 
6202  /* Support variables for precessing wfs*/
6203  REAL8 incl;
6204  REAL8 spin1x,spin1y,spin1z;
6205  REAL8 spin2x,spin2y,spin2z;
6206 
6207  /* Variables for IMRPhenomP and IMRPhenomPv2 */
6208  REAL8 chi1_l, chi2_l, chip, thetaJ, alpha0;
6209 
6210  /* General sanity checks that will abort
6211  *
6212  * If non-GR approximants are added, include them in
6213  * XLALSimInspiralApproximantAcceptTestGRParams()
6214  */
6216  XLALPrintError("XLAL Error - %s: Passed in non-NULL pointer to LALSimInspiralTestGRParam for an approximant that does not use LALSimInspiralTestGRParam\n", __func__);
6218  }
6219 
6220  /* General sanity check the input parameters - only give warnings! */
6221  if( deltaF > 1. )
6222  XLALPrintWarning("XLAL Warning - %s: Large value of deltaF = %e requested...This corresponds to a very short TD signal (with padding). Consider a smaller value.\n", __func__, deltaF);
6223  if( deltaF < 1./4096. )
6224  XLALPrintWarning("XLAL Warning - %s: Small value of deltaF = %e requested...This corresponds to a very long TD signal. Consider a larger value.\n", __func__, deltaF);
6225  if( m1 < 0.09 * LAL_MSUN_SI )
6226  XLALPrintWarning("XLAL Warning - %s: Small value of m1 = %e (kg) = %e (Msun) requested...Perhaps you have a unit conversion error?\n", __func__, m1, m1/LAL_MSUN_SI);
6227  if( m2 < 0.09 * LAL_MSUN_SI )
6228  XLALPrintWarning("XLAL Warning - %s: Small value of m2 = %e (kg) = %e (Msun) requested...Perhaps you have a unit conversion error?\n", __func__, m2, m2/LAL_MSUN_SI);
6229  if( m1 + m2 > 1000. * LAL_MSUN_SI )
6230  XLALPrintWarning("XLAL Warning - %s: Large value of total mass m1+m2 = %e (kg) = %e (Msun) requested...Signal not likely to be in band of ground-based detectors.\n", __func__, m1+m2, (m1+m2)/LAL_MSUN_SI);
6231  if( S1x*S1x + S1y*S1y + S1z*S1z > 1.000001 )
6232  XLALPrintWarning("XLAL Warning - %s: S1 = (%e,%e,%e) with norm > 1 requested...Are you sure you want to violate the Kerr bound?\n", __func__, S1x, S1y, S1z);
6233  if( S2x*S2x + S2y*S2y + S2z*S2z > 1.000001 )
6234  XLALPrintWarning("XLAL Warning - %s: S2 = (%e,%e,%e) with norm > 1 requested...Are you sure you want to violate the Kerr bound?\n", __func__, S2x, S2y, S2z);
6235  if( f_min < 1. )
6236  XLALPrintWarning("XLAL Warning - %s: Small value of fmin = %e requested...Check for errors, this could create a very long waveform.\n", __func__, f_min);
6237  if( f_min > 40.000001 )
6238  XLALPrintWarning("XLAL Warning - %s: Large value of fmin = %e requested...Check for errors, the signal will start in band.\n", __func__, f_min);
6239 
6240  /* adjust the reference frequency for certain precessing approximants:
6241  * if that approximate interprets f_ref==0 to be f_min, set f_ref=f_min;
6242  * otherwise do nothing */
6244 
6245  /* The non-precessing waveforms return h(f) for optimal orientation
6246  * (i=0, Fp=1, Fc=0; Lhat pointed toward the observer)
6247  * To get generic polarizations we multiply by inclination dependence
6248  * and note hc(f) \propto -I * hp(f)
6249  * Non-precessing waveforms multiply hp by pfac, hc by -I*cfac
6250  */
6251  cfac = cos(inclination);
6252  pfac = 0.5 * (1. + cfac*cfac);
6253 
6254  switch (approximant)
6255  {
6256  /* inspiral-only models */
6257  case EccentricFD:
6258  /* Waveform-specific sanity checks */
6260  XLALSimInspiralGetFrameAxis(waveFlags) ) )
6261  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
6263  XLALSimInspiralGetModesChoice(waveFlags) ) )
6264  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
6265  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6266  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6267  /* Call the waveform driver routine */
6268  /* Note that for generic inclined eccentric waveforms
6269  * * it is not possible to decompose hc(f) \propto I * hp(f)
6270  * * we call both polarizations independently
6271  * */
6272  /*ret = XLALSimInspiralEFD(hptilde, hctilde, phiRef, deltaF, m1, m2,
6273  * f_min, f_max, i, r, lambda1, lambda2, phaseO);*/
6274  ret = XLALSimInspiralEFD(hptilde, hctilde, phiRef, deltaF, m1, m2,
6275  f_min, f_max, inclination, distance, (REAL8) XLALSimInspiralGetTestGRParam( nonGRparams, "inclination_azimuth"),
6276  eccentricity, phaseO);
6277  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6278  break;
6279 
6280  case TaylorF2:
6281  /* Waveform-specific sanity checks */
6283  XLALSimInspiralGetFrameAxis(waveFlags) ) )
6284  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
6286  XLALSimInspiralGetModesChoice(waveFlags) ) )
6287  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
6288  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6289  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6290  XLAL_PRINT_DEPRECATION_WARNING("Calling TF2 via old interface, setting to default values tidal lambdas, quad-monopole pars, amplitude and phase order");
6291  /* Call the waveform driver routine */
6292  ret = XLALSimInspiralTaylorF2(hptilde, phiRef, deltaF, m1, m2,
6293  S1z, S2z, f_min, f_max, f_ref, distance,
6294  NULL);
6295  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6296  /* Produce both polarizations */
6297  *hctilde = XLALCreateCOMPLEX16FrequencySeries("FD hcross",
6298  &((*hptilde)->epoch), (*hptilde)->f0, (*hptilde)->deltaF,
6299  &((*hptilde)->sampleUnits), (*hptilde)->data->length);
6300  for(j = 0; j < (*hptilde)->data->length; j++) {
6301  (*hctilde)->data->data[j] = -I*cfac * (*hptilde)->data->data[j];
6302  (*hptilde)->data->data[j] *= pfac;
6303  }
6304  break;
6305 
6306  case TaylorF2NLTides:
6307  /* Waveform-specific sanity checks */
6309  XLALSimInspiralGetFrameAxis(waveFlags) ) )
6310  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
6312  XLALSimInspiralGetModesChoice(waveFlags) ) )
6313  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
6314  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6315  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6316  XLAL_PRINT_DEPRECATION_WARNING("Calling TF2 via old interface, setting to default values tidal lambdas, quad-monopole pars, amplitude and phase order");
6317 
6318  // FIXME : add checks for NL tidal parameters?
6319 
6320  /* Call the waveform driver routine */
6321  ret = XLALSimInspiralTaylorF2NLTides(hptilde, phiRef, deltaF, m1, m2,
6322  S1z, S2z, f_min, f_max, f_ref, distance,
6323  NULL);
6324  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6325  /* Produce both polarizations */
6326  *hctilde = XLALCreateCOMPLEX16FrequencySeries("FD hcross",
6327  &((*hptilde)->epoch), (*hptilde)->f0, (*hptilde)->deltaF,
6328  &((*hptilde)->sampleUnits), (*hptilde)->data->length);
6329  for(j = 0; j < (*hptilde)->data->length; j++) {
6330  (*hctilde)->data->data[j] = -I*cfac * (*hptilde)->data->data[j];
6331  (*hptilde)->data->data[j] *= pfac;
6332  }
6333  break;
6334 
6335  /* non-spinning inspiral-merger-ringdown models */
6336  case IMRPhenomA:
6337  /* Waveform-specific sanity checks */
6339  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6340  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
6341  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
6342  if( !checkTidesZero(lambda1, lambda2) )
6343  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6344  /* Call the waveform driver routine */
6345  ret = XLALSimIMRPhenomAGenerateFD(hptilde, phiRef, deltaF, m1, m2,
6346  f_min, f_max, distance);
6347  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6348  /* Produce both polarizations */
6349  *hctilde = XLALCreateCOMPLEX16FrequencySeries("FD hcross",
6350  &((*hptilde)->epoch), (*hptilde)->f0, (*hptilde)->deltaF,
6351  &((*hptilde)->sampleUnits), (*hptilde)->data->length);
6352  for(j = 0; j < (*hptilde)->data->length; j++) {
6353  (*hctilde)->data->data[j] = -I*cfac * (*hptilde)->data->data[j];
6354  (*hptilde)->data->data[j] *= pfac;
6355  }
6356  break;
6357 
6358  /* spinning inspiral-only models */
6359  case SpinTaylorF2:
6360  /* Waveform-specific sanity checks */
6361  /* Sanity check unused fields of waveFlags */
6363  XLALSimInspiralGetFrameAxis(waveFlags) ) )
6364  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
6366  XLALSimInspiralGetModesChoice(waveFlags) ) )
6367  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
6368  if( !checkCOSpinZero(S2x, S2y, S2z) ) // This is a single-spin model
6369  XLAL_ERROR(XLAL_EINVAL, "Non-zero CO spin given, but this approximant does not support this case.");
6370  spin1x=S1x;
6371  spin1y=S1y;
6372  spin1z=S1z;
6373  ROTATEY(inclination, spin1x, spin1y, spin1z);
6374  LNhatx = sin(inclination);
6375  LNhaty = 0.;
6376  LNhatz = cos(inclination);
6377  /* Maximum PN amplitude order for precessing waveforms is
6378  * MAX_PRECESSING_AMP_PN_ORDER */
6379  amplitudeO = 0; /* amplitudeO <= MAX_PRECESSING_AMP_PN_ORDER ?
6380  amplitudeO : MAX_PRECESSING_AMP_PN_ORDER */;
6381  /* Call the waveform driver routine */
6382  ret = XLALSimInspiralSpinTaylorF2(hptilde, hctilde, phiRef, deltaF,
6383  m1, m2, spin1x, spin1y, spin1z, LNhatx, LNhaty, LNhatz,
6384  f_min, f_max, f_ref, distance,
6385  NULL, phaseO, amplitudeO);
6386  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6387  break;
6388 
6389  /* FIXME: Comment out this case, as I don't have its source code */
6390  //case TaylorR2F4:
6391  // /* Waveform-specific sanity checks */
6392  // if( !XLALSimInspiralWaveformFlagsIsDefault(waveFlags) )
6393  // XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6394  // if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6395  // XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6396  // /* Call the waveform driver routine */
6397  // ret = XLALSimInspiralTaylorR2F4(hptilde, phiRef, deltaF, m1, m2,
6398  // S1z, S2z, f_min, r, phaseO, amplitudeO);
6399  // break;
6400 
6401  case TaylorF2RedSpin:
6402  /* Waveform-specific sanity checks */
6404  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6405  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6406  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6407  if( !checkTidesZero(lambda1, lambda2) )
6408  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6409  /* Call the waveform driver routine */
6410  ret = XLALSimInspiralTaylorF2ReducedSpin(hptilde, phiRef, deltaF,
6411  m1, m2, XLALSimInspiralTaylorF2ReducedSpinComputeChi(m1, m2, S1z, S2z),
6412  f_min, f_max, distance, phaseO, amplitudeO);
6413  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6414  /* Produce both polarizations */
6415  *hctilde = XLALCreateCOMPLEX16FrequencySeries("FD hcross",
6416  &((*hptilde)->epoch), (*hptilde)->f0, (*hptilde)->deltaF,
6417  &((*hptilde)->sampleUnits), (*hptilde)->data->length);
6418  for(j = 0; j < (*hptilde)->data->length; j++) {
6419  (*hctilde)->data->data[j] = -I*cfac * (*hptilde)->data->data[j];
6420  (*hptilde)->data->data[j] *= pfac;
6421  }
6422  break;
6423 
6424  case TaylorF2RedSpinTidal:
6425  /* Waveform-specific sanity checks */
6427  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6428  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6429  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6430  /* Call the waveform driver routine */
6431  ret = XLALSimInspiralTaylorF2ReducedSpinTidal(hptilde,phiRef,deltaF,
6432  m1, m2, XLALSimIMRPhenomBComputeChi(m1, m2, S1z, S2z),
6433  lambda1, lambda2, f_min, f_max, distance, phaseO, amplitudeO);
6434  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6435  /* Produce both polarizations */
6436  *hctilde = XLALCreateCOMPLEX16FrequencySeries("FD hcross",
6437  &((*hptilde)->epoch), (*hptilde)->f0, (*hptilde)->deltaF,
6438  &((*hptilde)->sampleUnits), (*hptilde)->data->length);
6439  for(j = 0; j < (*hptilde)->data->length; j++) {
6440  (*hctilde)->data->data[j] = -I*cfac * (*hptilde)->data->data[j];
6441  (*hptilde)->data->data[j] *= pfac;
6442  }
6443  break;
6444 
6445  /* spinning inspiral-merger-ringdown models */
6446  case IMRPhenomB:
6447  /* Waveform-specific sanity checks */
6449  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6450  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6451  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6452  if( !checkTidesZero(lambda1, lambda2) )
6453  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6454  /* Call the waveform driver routine */
6455  ret = XLALSimIMRPhenomBGenerateFD(hptilde, phiRef, deltaF, m1, m2,
6456  XLALSimIMRPhenomBComputeChi(m1, m2, S1z, S2z),
6457  f_min, f_max, distance);
6458  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6459  /* Produce both polarizations */
6460  *hctilde = XLALCreateCOMPLEX16FrequencySeries("FD hcross",
6461  &((*hptilde)->epoch), (*hptilde)->f0, (*hptilde)->deltaF,
6462  &((*hptilde)->sampleUnits), (*hptilde)->data->length);
6463  for(j = 0; j < (*hptilde)->data->length; j++) {
6464  (*hctilde)->data->data[j] = -I*cfac * (*hptilde)->data->data[j];
6465  (*hptilde)->data->data[j] *= pfac;
6466  }
6467  break;
6468 
6469  case IMRPhenomC:
6470  /* Waveform-specific sanity checks */
6472  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6473  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6474  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6475  if( !checkTidesZero(lambda1, lambda2) )
6476  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6477  /* Call the waveform driver routine */
6478  ret = XLALSimIMRPhenomCGenerateFD(hptilde, phiRef, deltaF, m1, m2,
6479  XLALSimIMRPhenomBComputeChi(m1, m2, S1z, S2z),
6480  f_min, f_max, distance, NULL);
6481  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6482  /* Produce both polarizations */
6483  *hctilde = XLALCreateCOMPLEX16FrequencySeries("FD hcross",
6484  &((*hptilde)->epoch), (*hptilde)->f0, (*hptilde)->deltaF,
6485  &((*hptilde)->sampleUnits), (*hptilde)->data->length);
6486  for(j = 0; j < (*hptilde)->data->length; j++) {
6487  (*hctilde)->data->data[j] = -I*cfac * (*hptilde)->data->data[j];
6488  (*hptilde)->data->data[j] *= pfac;
6489  }
6490  break;
6491 
6492  case IMRPhenomD:
6493  /* Waveform-specific sanity checks */
6495  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6496  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6497  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6498  if( !checkTidesZero(lambda1, lambda2) )
6499  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6500  /* Call the waveform driver routine */
6501 
6502  ret = XLALSimIMRPhenomDGenerateFD(hptilde, phiRef, f_ref, deltaF, m1, m2,
6503  S1z, S2z, f_min, f_max, distance, NULL, NoNRT_V);
6504  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6505  /* Produce both polarizations */
6506  *hctilde = XLALCreateCOMPLEX16FrequencySeries("FD hcross",
6507  &((*hptilde)->epoch), (*hptilde)->f0, (*hptilde)->deltaF,
6508  &((*hptilde)->sampleUnits), (*hptilde)->data->length);
6509  for(j = 0; j < (*hptilde)->data->length; j++) {
6510  (*hctilde)->data->data[j] = -I*cfac * (*hptilde)->data->data[j];
6511  (*hptilde)->data->data[j] *= pfac;
6512  }
6513  break;
6514 
6515  case EOBNRv2_ROM:
6516  /* Waveform-specific sanity checks */
6518  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6519  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
6520  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
6521  if( !checkTidesZero(lambda1, lambda2) )
6522  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6523 
6524  ret = XLALSimIMREOBNRv2HMROM(hptilde, hctilde,
6525  phiRef, deltaF, f_min, f_max, f_ref, distance, inclination, m1, m2, 0);
6526  break;
6527 
6528  case EOBNRv2HM_ROM:
6529  /* Waveform-specific sanity checks */
6531  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6532  if( !checkSpinsZero(S1x, S1y, S1z, S2x, S2y, S2z) )
6533  XLAL_ERROR(XLAL_EINVAL, "Non-zero spins were given, but this is a non-spinning approximant.");
6534  if( !checkTidesZero(lambda1, lambda2) )
6535  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6536 
6537  ret = XLALSimIMREOBNRv2HMROM(hptilde, hctilde,
6538  phiRef, deltaF, f_min, f_max, f_ref, distance, inclination, m1, m2, 1);
6539  break;
6540 
6542  /* Waveform-specific sanity checks */
6544  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6545  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6546  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6547  if( !checkTidesZero(lambda1, lambda2) )
6548  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6549  if (!checkAlignedSpinsEqual(S1z, S2z)) {
6550  XLALPrintError("XLAL Error - %s: SEOBNRv1ROM Effective Spin model called with unequal aligned spins: %lf, %lf.\n", __func__,S1z,S2z);
6552  }
6553 
6554  ret = XLALSimIMRSEOBNRv1ROMEffectiveSpin(hptilde, hctilde,
6555  phiRef, deltaF, f_min, f_max, f_ref, distance, inclination, m1, m2, XLALSimIMRPhenomBComputeChi(m1, m2, S1z, S2z));
6556  break;
6557 
6559  /* Waveform-specific sanity checks */
6561  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6562  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6563  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6564  if( !checkTidesZero(lambda1, lambda2) )
6565  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6566 
6567  ret = XLALSimIMRSEOBNRv1ROMDoubleSpin(hptilde, hctilde,
6568  phiRef, deltaF, f_min, f_max, f_ref, distance, inclination, m1, m2, S1z, S2z);
6569  break;
6570 
6572  /* Waveform-specific sanity checks */
6574  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6575  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6576  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6577  if( !checkTidesZero(lambda1, lambda2) )
6578  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6579  if (!checkAlignedSpinsEqual(S1z, S2z)) {
6580  XLALPrintError("XLAL Error - %s: SEOBNRv2ROM Effective Spin model called with unequal aligned spins: %lf, %lf.\n", __func__,S1z,S2z);
6582  }
6583 
6584  ret = XLALSimIMRSEOBNRv2ROMEffectiveSpin(hptilde, hctilde,
6585  phiRef, deltaF, f_min, f_max, f_ref, distance, inclination, m1, m2, XLALSimIMRPhenomBComputeChi(m1, m2, S1z, S2z));
6586  break;
6587 
6589  /* Waveform-specific sanity checks */
6591  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6592  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6593  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6594  if( !checkTidesZero(lambda1, lambda2) )
6595  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6596 
6597  ret = XLALSimIMRSEOBNRv2ROMDoubleSpin(hptilde, hctilde,
6598  phiRef, deltaF, f_min, f_max, f_ref, distance, inclination, m1, m2, S1z, S2z);
6599  break;
6600 
6602  /* Waveform-specific sanity checks */
6604  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralWaveformFlags given, but this approximant does not support this case.");
6605  if( !checkTransverseSpinsZero(S1x, S1y, S2x, S2y) )
6606  XLAL_ERROR(XLAL_EINVAL, "Non-zero transverse spins were given, but this is a non-precessing approximant.");
6607  if( !checkTidesZero(lambda1, lambda2) )
6608  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6609 
6610  ret = XLALSimIMRSEOBNRv2ROMDoubleSpinHI(hptilde, hctilde,
6611  phiRef, deltaF, f_min, f_max, f_ref, distance, inclination, m1, m2, S1z, S2z, -1);
6612  break;
6613 
6614 
6615  case IMRPhenomP:
6616  /* Waveform-specific sanity checks */
6617  XLALSimInspiralInitialConditionsPrecessingApproxs(&incl,&spin1x,&spin1y,&spin1z,&spin2x,&spin2y,&spin2z,inclination,S1x,S1y,S1z,S2x,S2y,S2z,m1,m2,f_ref,phiRef,XLALSimInspiralGetFrameAxis(waveFlags));
6618  if( !XLALSimInspiralModesChoiceIsDefault( /* Default is (2,2) or l=2 modes. */
6619  XLALSimInspiralGetModesChoice(waveFlags) ) )
6620  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
6621  if( !checkTidesZero(lambda1, lambda2) )
6622  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6623  LNhatx = sin(incl);
6624  LNhaty = 0.;
6625  LNhatz = cos(incl);
6626  /* Tranform to model parameters */
6627  if(f_ref==0.0)
6628  f_ref = f_min; /* Default reference frequency is minimum frequency */
6630  &chi1_l, &chi2_l, &chip, &thetaJ, &alpha0,
6631  m1, m2, f_ref,
6632  LNhatx, LNhaty, LNhatz,
6633  spin1x, spin1y, spin1z,
6634  spin2x, spin2y, spin2z, IMRPhenomPv1_V);
6635  /* Call the waveform driver routine */
6636  ret = XLALSimIMRPhenomP(hptilde, hctilde,
6637  chi1_l, chi2_l, chip, thetaJ,
6638  m1, m2, distance, alpha0, phiRef, deltaF, f_min, f_max, f_ref, IMRPhenomPv1_V, NoNRT_V, NULL);
6639  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6640  break;
6641 
6642  case IMRPhenomPv2:
6643  /* Waveform-specific sanity checks */
6644  XLALSimInspiralInitialConditionsPrecessingApproxs(&incl,&spin1x,&spin1y,&spin1z,&spin2x,&spin2y,&spin2z,inclination,S1x,S1y,S1z,S2x,S2y,S2z,m1,m2,f_ref,phiRef,XLALSimInspiralGetFrameAxis(waveFlags));
6645  if( !XLALSimInspiralModesChoiceIsDefault( /* Default is (2,2) or l=2 modes. */
6646  XLALSimInspiralGetModesChoice(waveFlags) ) )
6647  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
6648  if( !checkTidesZero(lambda1, lambda2) )
6649  XLAL_ERROR(XLAL_EINVAL, "Non-zero tidal parameters were given, but this is approximant doe not have tidal corrections.");
6650  LNhatx = sin(incl);
6651  LNhaty = 0.;
6652  LNhatz = cos(incl);
6653  /* Tranform to model parameters */
6654  if(f_ref==0.0)
6655  f_ref = f_min; /* Default reference frequency is minimum frequency */
6657  &chi1_l, &chi2_l, &chip, &thetaJ, &alpha0,
6658  m1, m2, f_ref,
6659  LNhatx, LNhaty, LNhatz,
6660  spin1x, spin1y, spin1z,
6661  spin2x, spin2y, spin2z, IMRPhenomPv2_V);
6662  /* Call the waveform driver routine */
6663  ret = XLALSimIMRPhenomP(hptilde, hctilde,
6664  chi1_l, chi2_l, chip, thetaJ,
6665  m1, m2, distance, alpha0, phiRef, deltaF, f_min, f_max, f_ref, IMRPhenomPv2_V, NoNRT_V, NULL);
6666  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6667  break;
6668 
6669  case SpinTaylorT4Fourier:
6670  /* Waveform-specific sanity checks */
6672  XLALSimInspiralGetFrameAxis(waveFlags) ) )
6673  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
6675  XLALSimInspiralGetModesChoice(waveFlags) ) )
6676  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
6677  spin1x=S1x;
6678  spin1y=S1y;
6679  spin1z=S1z;
6680  spin2x=S2x;
6681  spin2y=S2y;
6682  spin2z=S2z;
6683  ROTATEY(inclination,spin1x,spin1y,spin1z);
6684  ROTATEY(inclination,spin2x,spin2y,spin2z);
6685  LNhatx = sin(inclination);
6686  LNhaty = 0.;
6687  LNhatz = cos(inclination);
6688  E1x = 0.;
6689  E1y = 1.;
6690  E1z = 0.;
6691  // default kMax = 3
6692  kMax = 3;
6693  // default v0 = 1
6694  v0 = 1.;
6695  // default fStart = 0.9*fMin
6696  fStart = 0.9*f_min;
6697  phiRefAtEnd = 0;
6698  // if f_ref = 0, set it to f_min, and tell the driver routine that we came from there
6699  if(f_ref == 0)
6700  {
6701  f_ref = f_min;
6702  phiRefAtEnd = 1;
6703  }
6704  // default quadparams are for black holes. Replace by ~2-12 for neutron stars
6705  /* Call the waveform driver routine */
6706  ret = XLALSimInspiralSpinTaylorT4Fourier(hptilde, hctilde,
6707  f_min, f_max, deltaF, kMax, phiRef, v0, m1, m2, fStart, f_ref, distance, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z, LNhatx, LNhaty, LNhatz, E1x, E1y, E1z, lambda1, lambda2, quadparam1, quadparam2, NULL, phaseO, amplitudeO, phiRefAtEnd);
6708  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6709  break;
6710 
6711  case SpinTaylorT5Fourier:
6712  /* Waveform-specific sanity checks */
6714  XLALSimInspiralGetFrameAxis(waveFlags) ) )
6715  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralFrameAxis provided, but this approximant does not use that flag.");
6717  XLALSimInspiralGetModesChoice(waveFlags) ) )
6718  XLAL_ERROR(XLAL_EINVAL, "Non-default LALSimInspiralModesChoice provided, but this approximant does not use that flag.");
6719  spin1x=S1x;
6720  spin1y=S1y;
6721  spin1z=S1z;
6722  spin2x=S2x;
6723  spin2y=S2y;
6724  spin2z=S2z;
6725  ROTATEY(inclination,spin1x,spin1y,spin1z);
6726  ROTATEY(inclination,spin2x,spin2y,spin2z);
6727  LNhatx = sin(inclination);
6728  LNhaty = 0.;
6729  LNhatz = cos(inclination);
6730  E1x = 0.;
6731  E1y = 1.;
6732  E1z = 0.;
6733  // default kMax = 3
6734  kMax = 3;
6735  // default v0 = 1
6736  v0 = 1.;
6737  // default fStart = 0.9*fMin
6738  fStart = 0.9*f_min;
6739  phiRefAtEnd = 0;
6740  // if f_ref = 0, set it to f_min, and tell the driver routine that we came from there
6741  if(f_ref == 0)
6742  {
6743  f_ref = f_min;
6744  phiRefAtEnd = 1;
6745  }
6746  // default quadparams are for black holes. Replace by ~2-12 for neutron stars
6747  /* Call the waveform driver routine */
6748  ret = XLALSimInspiralSpinTaylorT5Fourier(hptilde, hctilde,
6749  f_min, f_max, deltaF, kMax, phiRef, v0, m1, m2, fStart, f_ref, distance, spin1x, spin1y, spin1z, spin2x, spin2y, spin2z, LNhatx, LNhaty, LNhatz, E1x, E1y, E1z, lambda1, lambda2, quadparam1, quadparam2, NULL, phaseO, amplitudeO, phiRefAtEnd);
6750  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6751  break;
6752 
6753 
6754  default:
6755  XLALPrintError("FD version of approximant not implemented in lalsimulation\n");
6757  }
6758 
6759  REAL8 polariz=longAscNodes;
6760  if (polariz) {
6761  COMPLEX16 tmpP,tmpC;
6762  for (UINT4 idx=0;idx<(*hptilde)->data->length;idx++) {
6763  tmpP=(*hptilde)->data->data[idx];
6764  tmpC=(*hctilde)->data->data[idx];
6765  (*hptilde)->data->data[idx] =cos(2.*polariz)*tmpP+sin(2.*polariz)*tmpC;
6766  (*hctilde)->data->data[idx]=cos(2.*polariz)*tmpC-sin(2.*polariz)*tmpP;
6767  }
6768  }
6769 
6770  if (ret == XLAL_FAILURE) XLAL_ERROR(XLAL_EFUNC);
6771 
6772  return ret;
6773 }
6774 
6775 /**
6776  * if you do NOT provide a quadparam[1,2] term and you DO provide
6777  * lamdba[1,2] then we calculate quad-mono term using universal relations
6778  * quadparam[1,2]_UR: Quadrupole-Monopole parameter computed using
6779  * universal relations (UR)
6780  */
6781 
6783  LALDict *LALparams /**< LAL dictionary containing accessory parameters */
6784  )
6785 {
6786  REAL8 quadparam1 = XLALSimInspiralWaveformParamsLookupdQuadMon1(LALparams);
6787  REAL8 quadparam2 = XLALSimInspiralWaveformParamsLookupdQuadMon2(LALparams);
6790 
6791  if ((lambda1 > 0) && (quadparam1 == 0)) {
6792  REAL8 quadparam1_UR = XLALSimInspiralEOSQfromLambda(lambda1);
6793  XLALSimInspiralWaveformParamsInsertdQuadMon1(LALparams, quadparam1_UR - 1.);
6794  }
6795 
6796  if ((lambda2 > 0) && (quadparam2 == 0)) {
6797  REAL8 quadparam2_UR = XLALSimInspiralEOSQfromLambda(lambda2);
6798  XLALSimInspiralWaveformParamsInsertdQuadMon2(LALparams, quadparam2_UR - 1.);
6799  }
6800  return XLAL_SUCCESS;
6801 }
6802 /** @} */
int XLALHighPassCOMPLEX16TimeSeries(COMPLEX16TimeSeries *series, REAL8 frequency, REAL8 amplitude, INT4 filtorder)
int XLALHighPassREAL8TimeSeries(REAL8TimeSeries *series, REAL8 frequency, REAL8 amplitude, INT4 filtorder)
REAL8 zeta
int XLALDictContains(const LALDict *dict, const char *key)
int XLALDictRemove(LALDict *dict, const char *key)
void XLALDestroyDict(LALDict *dict)
LALDict * XLALDictDuplicate(LALDict *old)
LALDict * XLALCreateDict(void)
int XLALDictInsertINT4Value(LALDict *dict, const char *key, INT4 value)
INT4 XLALSimIMREOBGenerateQNMFreqV5(COMPLEX16Vector *modefreqs, const REAL8 mass1, const REAL8 mass2, const REAL8 spin1[3], const REAL8 spin2[3], UINT4 l, INT4 m, UINT4 nmodes, Approximant approximant)
These functions generate the quasinormal mode frequencies for a black hole ringdown,...
int XLALSimIMRPhenSpinInspiralRDGenerator(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phi0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 f_ref, REAL8 r, REAL8 iota, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, int phaseO, int ampO, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams)
double XLALIMRPhenomDGetPeakFreq(const REAL8 m1_in, const REAL8 m2_in, const REAL8 chi1_in, const REAL8 chi2_in)
Function to return the frequency (in Hz) of the peak of the frequency domain amplitude for the IMRPhe...
int XLALSimInspiralNRWaveformGetHplusHcross(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 inclination, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 r, REAL8 fStart, REAL8 fRef, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, const char *NRDataFile, LALValue *ModeArray)
int XLALSimIMREOBNRv2HMROM(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 deltaF, REAL8 fLow, REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 m1SI, REAL8 m2SI, const int higherModesFlag)
int XLALSimSpinInspiralGenerator(REAL8TimeSeries **hPlus, REAL8TimeSeries **hCross, REAL8 phi_start, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 f_ref, REAL8 r, REAL8 iota, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, int phaseO, int ampO, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams)
int XLALSimIMRSpinEOBWaveform(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const REAL8 phiC, const REAL8 deltaT, const REAL8 m1SI, const REAL8 m2SI, const REAL8 fMin, const REAL8 r, const REAL8 inc, const REAL8 spin1[], const REAL8 spin2[], const UINT4 PrecEOBversion)
Standard interface for SEOBNRv3 waveform generator: calls XLALSimIMRSpinEOBWaveformAll.
const double c2
const double c0
#define ROTATEZ(angle, vx, vy, vz)
#define ROTATEY(angle, vx, vy, vz)
REAL8 XLALSimInspiralChirpStartFrequencyBound(REAL8 tchirp, REAL8 m1, REAL8 m2)
Routine to compute an underestimate of the starting frequency for a given chirp time.
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.
int XLALSimInspiralGetTaperFromString(const char *string)
Parses a string to determine the LALSimInspiralApplyTaper enum value.
static const char * lalSimulationTaperNames[]
int XLALGetTaperFromString(const char *string)
int XLALSimInspiralTDConditionStage1(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, REAL8 textra, REAL8 f_min)
First stage of conditioning of time-domain waveforms.
const char * XLALGetStringFromApproximant(Approximant approximant)
int XLALSimInspiralGetSpinFreqFromApproximant(Approximant approx)
const char * XLALSimInspiralGetStringFromFrameAxis(LALSimInspiralFrameAxis axis)
Returns a string associated with a LALSimInspiralFrameAxis enum value.
int XLALSimInspiralApproximantAcceptTestGRParams(Approximant approx)
const char * XLALSimInspiralGetStringFromApproximant(Approximant approximant)
Returns a string associated with an Approximant enum value.
#define DELETE_SUBSTRING_IN_LIST_FROM_STRING(string, list)
int XLALGetOrderFromString(const char *waveform)
REAL8 XLALSimInspiralMergeTimeBound(REAL8 m1, REAL8 m2)
Routine to compute an overestimate of the merger time.
static const char * lalSimulationModesChoiceNames[]
int XLALSimInspiralGetPNOrderFromString(const char *waveform)
Parses a waveform string to determine PN order.
int XLALGetApproximantFromString(const char *waveform)
const char * XLALSimInspiralGetStringFromPNOrder(LALPNOrder order)
Returns a string associated with a LALPNOrder enum value.
int XLALSimInspiralChooseFDWaveformOLD(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, const REAL8 lambda1, const REAL8 lambda2, const REAL8 dQuadParam1, const REAL8 dQuadParam2, LALSimInspiralWaveformFlags *waveFlags, LALSimInspiralTestGRParam *nonGRparams, int amplitudeO, const int phaseO, const Approximant approximant)
int XLALSimInspiralGetHigherModesFromString(const char *string)
Parses a string to determine the LALSimInspiralModesChoice enum value.
double XLALSimInspiralGetFrequency(REAL8 m1, REAL8 m2, const REAL8 S1x, const REAL8 S1y, const REAL8 S1z, const REAL8 S2x, const REAL8 S2y, const REAL8 S2z, FrequencyFunction freqFunc)
Function that gives the value of the desired frequency given some physical parameters.
const char * XLALSimInspiralGetStringFromTaper(LALSimInspiralApplyTaper taper)
Returns a string associated with a LALSimInspiralApplyTaper enum value.
#define MAX_PRECESSING_AMP_PN_ORDER
(Twice) the highest known PN order of amplitude correction for precessing binaries.
int XLALGetHigherModesFromString(const char *string)
int XLALGetFrameAxisFromString(const char *waveform)
static const char * lalSimulationFrameAxisNames[]
REAL8 XLALSimInspiralfLow2fStart(REAL8 fLow, INT4 ampOrder, INT4 approximant)
Function for determining the starting frequency of the (2,2) mode when the highest order contribution...
int XLALSimInspiralImplementedFDApproximants(Approximant approximant)
Checks whether the given approximant is implemented in lalsimulation's XLALSimInspiralChooseFDWavefor...
const char * XLALSimInspiralGetStringFromModesChoice(LALSimInspiralModesChoice modes)
Returns a string associated with a LALSimInspiralModesChoice enum value.
int XLALSimInspiralGetAllowZeroMinFreqFromApproximant(Approximant approx)
REAL8 XLALSimInspiralRingdownTimeBound(REAL8 M, REAL8 s)
Routine to compute an overestimate of the ringdown time.
#define INITIALIZE_NAME(a)
int XLALSimInspiralGetFrameAxisFromString(const char *waveform)
Parses a waveform string to determine frame axis.
const LALSimInspiralGenerator * lalSimInspiralGeneratorTemplates[NumApproximants]
REAL8 XLALSimInspiralFinalBlackHoleSpinBound(REAL8 S1z, REAL8 S2z)
Routine to compute an overestimate of a final black hole dimensionless spin.
int XLALSimInspiralDecomposeWaveformString(int *approximant, int *order, int *axis, const char *waveform)
Parses a waveform string to determine approximant, PN order, and axis choice.
double XLALSimInspiralGetFinalFreq(REAL8 m1, REAL8 m2, const REAL8 S1x, const REAL8 S1y, const REAL8 S1z, const REAL8 S2x, const REAL8 S2y, const REAL8 S2z, Approximant approximant)
Function that gives the default ending frequencies of the given approximant.
int XLALSimInspiralChooseTDWaveformOLD(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, const REAL8 lambda1, const REAL8 lambda2, const REAL8 dQuadParam1, const REAL8 dQuadParam2, LALSimInspiralWaveformFlags *waveFlags, LALSimInspiralTestGRParam *nonGRparams, int amplitudeO, const int phaseO, const Approximant approximant)
int XLALSimInspiralImplementedTDApproximants(Approximant approximant)
Checks whether the given approximant is implemented in lalsimulation's XLALSimInspiralChooseTDWavefor...
int XLALSimInspiralTDConditionStage2(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, REAL8 f_min, REAL8 f_max)
Second stage of conditioning of time-domain waveforms.
int XLALSimInspiralSetQuadMonParamsFromLambdas(LALDict *LALparams)
if you do NOT provide a quadparam[1,2] term and you DO provide lamdba[1,2] then we calculate quad-mon...
static const char * lalSimulationPNOrderNames[]
int XLALSimLorentzInvarianceViolationTerm(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, REAL8 m1, REAL8 m2, REAL8 r, LALDict *LALparams)
static const char * lalSimulationApproximantNames[]
int XLALSimInspiralGetSpinSupportFromApproximant(Approximant approx)
#define MAX_NONPRECESSING_AMP_PN_ORDER
(Twice) the highest known PN order of amplitude correction for non-precessing binaries.
static int delete_substring_in_list_from_string(char *string, const char *list[], size_t size)
int XLALSimInspiralGetApproximantFromString(const char *waveform)
Parses a waveform string to determine approximant.
COMPLEX16TimeSeries * XLALSimInspiralTaylorT2PNMode(REAL8 v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 fRef, REAL8 r, REAL8 lambda1, REAL8 lambda2, LALSimInspiralTidalOrder tideO, int amplitudeO, int phaseO, int l, int m)
const LALSimInspiralGenerator lalSEOBNRv4_ROMGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv1GeneratorTemplate
const LALSimInspiralGenerator lalLackey_Tidal_2013_SEOBNRv2_ROMGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomDGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomPv3GeneratorTemplate
const LALSimInspiralGenerator lalSpinTaylorT5FourierGeneratorTemplate
COMPLEX16TimeSeries * XLALSimInspiralTaylorT1PNMode(REAL8 v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 fRef, REAL8 r, REAL8 lambda1, REAL8 lambda2, LALSimInspiralTidalOrder tideO, int amplitudeO, int phaseO, int l, int m)
const LALSimInspiralGenerator lalTaylorEtGeneratorTemplate
const LALSimInspiralGenerator lalNRSur7dq4GeneratorTemplate
const LALSimInspiralGenerator lalSpinTaylorT1GeneratorTemplate
int XLALSimInspiralEFD(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, const REAL8 phiRef, const REAL8 deltaF, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 fStart, const REAL8 fEnd, const REAL8 i, const REAL8 r, const REAL8 inclination_azimuth, const REAL8 e_min, int phaseO)
const LALSimInspiralGenerator lalIMRPhenomPv3HMGeneratorTemplate
const LALSimInspiralGenerator lalSpinDominatedWfGeneratorTemplate
const LALSimInspiralGenerator lalNRSur4d2sGeneratorTemplate
const LALSimInspiralGenerator lalNRHybSur3dq8GeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomPGeneratorTemplate
const LALSimInspiralGenerator lalTaylorR2F4GeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomTPHMGeneratorTemplate
int XLALSimInspiralSpinTaylorT4OLD(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams, int phaseO, int amplitudeO)
const LALSimInspiralGenerator lalNR_hdf5GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv3_pertGeneratorTemplate
const LALSimInspiralGenerator lalEOBNRv2_ROMGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomXPHMGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomAGeneratorTemplate
COMPLEX16TimeSeries * XLALSimInspiralTaylorT3PNMode(REAL8 v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 fRef, REAL8 r, REAL8 lambda1, REAL8 lambda2, LALSimInspiralTidalOrder tideO, int amplitudeO, int phaseO, int l, int m)
const LALSimInspiralGenerator lalTaylorT4GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv2_ROM_DoubleSpin_HIGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomTHMGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomPv2_NRTidalv2GeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomXASGeneratorTemplate
const LALSimInspiralGenerator lalEccentricTDGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomD_NRTidalGeneratorTemplate
const LALSimInspiralGenerator lalEOBNRv2GeneratorTemplate
const LALSimInspiralGenerator lalPythonGeneratorTemplate
const LALSimInspiralGenerator lalTaylorF2GeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomHMGeneratorTemplate
const LALSimInspiralGenerator lalTaylorF2RedSpinGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv1_ROM_DoubleSpinGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomXO4aGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomPv2GeneratorTemplate
const LALSimInspiralGenerator lalSpinTaylorF2GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv1_ROM_EffectiveSpinGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomXHMGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomTGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv5HM_ROMGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomXPGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv4T_surrogateGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomPv2_NRTidalGeneratorTemplate
const LALSimInspiralGenerator lalSpinTaylorT4GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv3_optGeneratorTemplate
const LALSimInspiralGenerator lalEccentricFDGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv4_optGeneratorTemplate
const LALSimInspiralGenerator lalTEOBResumSGeneratorTemplate
const LALSimInspiralGenerator lalSpinTaylorT5GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv4_ROM_NRTidalv2GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv2TGeneratorTemplate
const LALSimInspiralGenerator lalHGimriGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomCGeneratorTemplate
int XLALSimInspiralSpinTaylorT1OLD(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams, int phaseO, int amplitudeO)
int XLALSimInspiralTaylorT2PNGenerator(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 fRef, REAL8 r, REAL8 i, REAL8 lambda1, REAL8 lambda2, LALSimInspiralTidalOrder tideO, int amplitudeO, int phaseO)
const LALSimInspiralGenerator lalSpinTaylorT4FourierGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomXP_NRTidalv2GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv4PHMGeneratorTemplate
const LALSimInspiralGenerator lalTaylorF2NLTidesGeneratorTemplate
const LALSimInspiralGenerator lalTaylorT3GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv3_opt_rk4GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv4_ROM_NRTidalv2_NSBHGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv2GeneratorTemplate
const LALSimInspiralGenerator lalTaylorT2GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv3GeneratorTemplate
const LALSimInspiralGenerator lalEOBNRv2HMGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv4TGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv4HM_ROMGeneratorTemplate
const LALSimInspiralGenerator lalPhenSpinTaylorGeneratorTemplate
const LALSimInspiralGenerator lalPhenSpinTaylorRDGeneratorTemplate
const LALSimInspiralGenerator lalTEOBResum_ROMGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomXAS_NRTidalv2GeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv5_ROMGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomNSBHGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv4HM_PAGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv2_ROM_DoubleSpinGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv4PGeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomD_NRTidalv2GeneratorTemplate
const LALSimInspiralGenerator lalTaylorF2EccGeneratorTemplate
const LALSimInspiralGenerator lalpSEOBNRv4HM_PAGeneratorTemplate
int XLALSimInspiralTaylorT4PNGenerator(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 fRef, REAL8 r, REAL8 i, REAL8 lambda1, REAL8 lambda2, LALSimInspiralTidalOrder tideO, int amplitudeO, int phaseO)
COMPLEX16TimeSeries * XLALSimInspiralTaylorT4PNMode(REAL8 v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 fRef, REAL8 r, REAL8 lambda1, REAL8 lambda2, LALSimInspiralTidalOrder tideO, int amplitudeO, int phaseO, int l, int m)
const LALSimInspiralGenerator lalSEOBNRv4_ROM_NRTidalGeneratorTemplate
const LALSimInspiralGenerator lalEOBNRv2HM_ROMGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv2_ROM_EffectiveSpinGeneratorTemplate
const LALSimInspiralGenerator lalNRSur7dq2GeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomBGeneratorTemplate
const LALSimInspiralGenerator lalTaylorT1GeneratorTemplate
int XLALSimInspiralSpinDominatedWaveformInterfaceTD(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 D, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 incl, int phaseO, int amplitudeO, REAL8 phiRef)
Interface routine, calculating the prefered variables for the Spin-dominated waveforms.
const LALSimInspiralGenerator lalSEOBNRv4GeneratorTemplate
const LALSimInspiralGenerator lalIMRPhenomTPGeneratorTemplate
const LALSimInspiralGenerator lalTaylorF2RedSpinTidalGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv4HMGeneratorTemplate
const LALSimInspiralGenerator lalSEOBNRv2_optGeneratorTemplate
REAL8 XLALSimInspiralEOSQfromLambda(REAL8 lambda)
static double tau(const double a, const double b, const sysq *system)
Internal function that computes the spin-spin couplings.
static REAL8 UNUSED q3(REAL8 e0, REAL8 f0, REAL8 inc, REAL8 bet, REAL8 FPlus, REAL8 FCross)
static REAL8 UNUSED q2(REAL8 e0, REAL8 f0, REAL8 inc, REAL8 bet, REAL8 FPlus, REAL8 FCross)
static REAL8 UNUSED q1(REAL8 e0, REAL8 f0, REAL8 inc, REAL8 bet, REAL8 FPlus, REAL8 FCross)
static REAL8 UNUSED XLALSimInspiralTaylorT2Timing_2PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralLN(REAL8 M, REAL8 eta, REAL8 v)
static REAL8 UNUSED XLALSimInspiralTaylorT2Timing_4PNCoeff(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT3Frequency_0PNCoeff(REAL8 totalmass)
Computes the PN Coefficients for using in the TaylorT3 frequency equation.
static REAL8 UNUSED XLALSimInspiralL_2PN(REAL8 eta)
static REAL8 UNUSED XLALSimInspiralTaylorT2Timing_0PNCoeff(REAL8 totalmass, REAL8 eta)
Computes the PN Coefficients for using in the TaylorT2 timing equation.
REAL8 XLALSimInspiralWaveformParamsLookupMass1(LALDict *params)
Compute mass1 from any possible combination of 2 mass parameters inserted in the LALDict.
REAL8 XLALSimInspiralWaveformParamsLookupMass2(LALDict *params)
Compute mass2 from any possible combination of 2 mass parameters inserted in the LALDict.
REAL8 XLALSimInspiralWaveformParamsLookupSpin2y(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupSpin2x(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupSpin1x(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupSpin2z(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupSpin1z(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupSpin1y(LALDict *params)
int XLALSimInspiralWaveformParamsInsertSpin1z(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupNonGRLIVAlpha(LALDict *params)
int XLALSimInspiralWaveformParamsInsertMass1(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertF22Ref(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupF22Start(LALDict *params)
INT4 XLALSimInspiralWaveformParamsLookupEnableLIV(LALDict *params)
int XLALSimInspiralWaveformParamsInsertDeltaF(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertLongAscNodes(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupRedshift(LALDict *params)
int XLALSimInspiralWaveformParamsInsertSpin2z(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertRefPhase(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupRefPhase(LALDict *params)
int XLALSimInspiralWaveformParamsInsertSpin1y(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupNonGRLIVLogLambdaEff(LALDict *params)
int XLALSimInspiralWaveformParamsInsertMeanPerAno(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupdQuadMon1(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupDeltaF(LALDict *params)
int XLALSimInspiralWaveformParamsInsertEccentricity(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupTidalLambda2(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupLongAscNodes(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupInclination(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupDeltaT(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupFMax(LALDict *params)
int XLALSimInspiralWaveformParamsInsertInclination(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertDeltaT(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupMeanPerAno(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupTidalLambda1(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupDistance(LALDict *params)
int XLALSimInspiralWaveformParamsInsertSpin2x(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupNonGRLIVASign(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupdQuadMon2(LALDict *params)
int XLALSimInspiralWaveformParamsInsertF22Start(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertdQuadMon2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertdQuadMon1(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertRedshift(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertSpin2y(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertSpin1x(LALDict *params, REAL8 value)
REAL8 XLALSimInspiralWaveformParamsLookupEccentricity(LALDict *params)
REAL8 XLALSimInspiralWaveformParamsLookupF22Ref(LALDict *params)
int XLALSimInspiralWaveformParamsInsertFMax(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertLmax(LALDict *params, INT4 value)
INT4 XLALSimInspiralWaveformParamsLookupLmax(LALDict *params)
int XLALSimInspiralWaveformParamsInsertMass2(LALDict *params, REAL8 value)
int XLALSimInspiralWaveformParamsInsertDistance(LALDict *params, REAL8 value)
static REAL8 pfac(int n)
REAL8 tmp1
#define fprintf
int s
Definition: bh_qnmode.c:137
int l
Definition: bh_qnmode.c:135
REAL8 M
Definition: bh_qnmode.c:133
double dt
Definition: bh_ringdown.c:113
double i
Definition: bh_ringdown.c:118
double theta
Definition: bh_sphwf.c:118
#define LAL_CHECK_VALID_SERIES(s, val)
#define LAL_CHECK_CONSISTENT_TIME_SERIES(s1, s2, val)
#define checkCOSpinZero(s2x, s2y, s2z)
#define checkTransverseSpinsZero(s1x, s1y, s2x, s2y)
#define checkAlignedSpinsEqual(s1z, s2z)
#define checkSpinsZero(s1x, s1y, s1z, s2x, s2y, s2z)
#define checkTidesZero(lambda1, lambda2)
const double Q
const double u
const double ny
const double w
sigmaKerr data[0]
const double nz
const double nx
#define FIX_REFERENCE_FREQUENCY(f_ref, f_min, approximant)
#define __attribute__(x)
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALDestroyCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series)
#define LAL_PI_2
#define LAL_C_SI
#define LAL_MSUN_SI
#define LAL_PI
#define LAL_MTSUN_SI
#define LAL_GAMMA
#define LAL_G_SI
#define LAL_MRSUN_SI
double complex COMPLEX16
double REAL8
uint32_t UINT4
int32_t INT4
void * XLALMalloc(size_t n)
void XLALFree(void *p)
INT4 XLALSimIMREOBGenerateQNMFreqV2(COMPLEX16Vector *modefreqs, const REAL8 mass1, const REAL8 mass2, const REAL8 spin1[3], const REAL8 spin2[3], UINT4 l, INT4 m, UINT4 nmodes, Approximant approximant)
These functions generate the quasinormal mode frequencies for a black hole ringdown.
@ IMRPhenomPv1_V
version 1: based on IMRPhenomC
Definition: LALSimIMR.h:74
@ IMRPhenomPv2_V
version 2: based on IMRPhenomD
Definition: LALSimIMR.h:75
@ NoNRT_V
special case for PhenomPv2 BBH baseline
Definition: LALSimIMR.h:85
int XLALSimIMREOBNRv2AllModes(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const REAL8 phiC, const REAL8 deltaT, const REAL8 m1SI, const REAL8 m2SI, const REAL8 fLower, const REAL8 distance, const REAL8 inclination)
This function generates the plus and cross polarizations for the EOBNRv2 approximant with all availab...
SphHarmTimeSeries * XLALSimIMREOBNRv2Modes(const REAL8 deltaT, const REAL8 m1, const REAL8 m2, const REAL8 fLower, const REAL8 distance)
Wrapper function to generate the -2 spin-weighted spherical harmonic modes (as opposed to generating ...
int XLALSimIMREOBNRv2DominantMode(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const REAL8 phiC, const REAL8 deltaT, const REAL8 m1SI, const REAL8 m2SI, const REAL8 fLower, const REAL8 distance, const REAL8 inclination)
This function generates the plus and cross polarizations for the dominant (2,2) mode of the EOBNRv2 a...
double XLALSimIMRPhenomAGetFinalFreq(const REAL8 m1, const REAL8 m2)
Compute the default final frequency.
int XLALSimIMRPhenomBGenerateFD(COMPLEX16FrequencySeries **htilde, const REAL8 phiPeak, const REAL8 deltaF, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 chi, const REAL8 f_min, const REAL8 f_max, const REAL8 distance)
Driver routine to compute the spin-aligned, inspiral-merger-ringdown phenomenological waveform IMRPhe...
int XLALSimIMRPhenomP(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, const REAL8 chi1_l, const REAL8 chi2_l, const REAL8 chip, const REAL8 thetaJ, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 distance, const REAL8 alpha0, const REAL8 phic, const REAL8 deltaF, const REAL8 f_min, const REAL8 f_max, const REAL8 f_ref, IMRPhenomP_version_type IMRPhenomP_version, NRTidal_version_type NRTidal_version, LALDict *extraParams)
Driver routine to compute the precessing inspiral-merger-ringdown phenomenological waveform IMRPhenom...
int XLALSimIMRPhenomDGenerateFD(COMPLEX16FrequencySeries **htilde, const REAL8 phi0, const REAL8 fRef, const REAL8 deltaF, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 chi1, const REAL8 chi2, const REAL8 f_min, const REAL8 f_max, const REAL8 distance, LALDict *extraParams, NRTidal_version_type NRTidal_version)
Driver routine to compute the spin-aligned, inspiral-merger-ringdown phenomenological waveform IMRPhe...
double XLALSimIMRPhenomBComputeChi(const REAL8 m1, const REAL8 m2, const REAL8 s1z, const REAL8 s2z)
Compute the dimensionless, spin-aligned parameter chi as used in the IMRPhenomB waveform.
int XLALSimIMRPhenomPCalculateModelParametersOld(REAL8 *chi1_l, REAL8 *chi2_l, REAL8 *chip, REAL8 *thetaJ, REAL8 *alpha0, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 f_ref, const REAL8 lnhatx, const REAL8 lnhaty, const REAL8 lnhatz, const REAL8 s1x, const REAL8 s1y, const REAL8 s1z, const REAL8 s2x, const REAL8 s2y, const REAL8 s2z, IMRPhenomP_version_type IMRPhenomP_version)
Deprecated : used the old convention (view frame for the spins) Function to map LAL parameters (masse...
int XLALSimIMRPhenomAGenerateFD(COMPLEX16FrequencySeries **htilde, const REAL8 phiPeak, const REAL8 deltaF, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 f_min, const REAL8 f_max, const REAL8 distance)
Driver routine to compute the non-spinning, inspiral-merger-ringdown phenomenological waveform IMRPhe...
int XLALSimIMRPhenomAGenerateTD(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const REAL8 phiPeak, const REAL8 deltaT, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 f_min, const REAL8 f_max, const REAL8 distance, const REAL8 inclination)
Driver routine to compute the non-spinning, inspiral-merger-ringdown phenomenological waveform IMRPhe...
int XLALSimIMRPhenomCGenerateTD(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const REAL8 phiPeak, const REAL8 deltaT, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 chi, const REAL8 f_min, const REAL8 f_max, const REAL8 distance, const REAL8 inclination, LALDict *extraParams)
Driver routine to compute the spin-aligned, inspiral-merger-ringdown phenomenological waveform IMRPhe...
double XLALSimIMRPhenomBGetFinalFreq(const REAL8 m1, const REAL8 m2, const REAL8 chi)
Compute the default final frequency.
int XLALSimIMRPhenomCGenerateFD(COMPLEX16FrequencySeries **htilde, const REAL8 phiPeak, const REAL8 deltaF, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 chi, const REAL8 f_min, const REAL8 f_max, const REAL8 distance, LALDict *extraParams)
Driver routine to compute the spin-aligned, inspiral-merger-ringdown phenomenological waveform IMRPhe...
int XLALSimIMRPhenomBGenerateTD(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const REAL8 phiPeak, const REAL8 deltaT, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 chi, const REAL8 f_min, const REAL8 f_max, const REAL8 distance, const REAL8 inclination)
Driver routine to compute the spin-aligned, inspiral-merger-ringdown phenomenological waveform IMRPhe...
double XLALSimIMRPhenomCGetFinalFreq(const REAL8 m1, const REAL8 m2, const REAL8 chi)
Convenience function to quickly find the default final frequency.
int XLALSimIMRPhenomXPCalculateModelParametersFromSourceFrame(REAL8 *chi1L, REAL8 *chi2L, REAL8 *chi_p, REAL8 *thetaJN, REAL8 *alpha0, REAL8 *phi_aligned, REAL8 *zeta_polarization, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 f_ref, const REAL8 phiRef, const REAL8 incl, const REAL8 s1x, const REAL8 s1y, const REAL8 s1z, const REAL8 s2x, const REAL8 s2y, const REAL8 s2z, LALDict *lalParams)
int XLALSimIMRSEOBNRv2ROMDoubleSpin(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 deltaF, REAL8 fLow, REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2)
Compute waveform in LAL format for the SEOBNRv2_ROM_DoubleSpin model.
int XLALSimIMRSEOBNRv2ROMDoubleSpinHI(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 deltaF, REAL8 fLow, REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2, INT4 nk_max)
Compute waveform in LAL format for the SEOBNRv2_ROM_DoubleSpin_HI model.
int XLALSimIMRSEOBNRv1ROMEffectiveSpin(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 deltaF, REAL8 fLow, REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi)
Compute waveform in LAL format for the SEOBNRv1_ROM_EffectiveSpin model.
int XLALSimIMRSEOBNRv2ROMEffectiveSpin(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 deltaF, REAL8 fLow, REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi)
Compute waveform in LAL format for the SEOBNRv2_ROM_EffectiveSpin model.
int XLALSimIMRSEOBNRv1ROMDoubleSpin(struct tagCOMPLEX16FrequencySeries **hptilde, struct tagCOMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 deltaF, REAL8 fLow, REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2)
Compute waveform in LAL format for the SEOBNRv1_ROM_DoubleSpin model.
int XLALSimIMRSpinAlignedEOBWaveform(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, const REAL8 phiC, REAL8 deltaT, const REAL8 m1SI, const REAL8 m2SI, const REAL8 fMin, const REAL8 r, const REAL8 inc, const REAL8 spin1z, const REAL8 spin2z, UINT4 SpinAlignedEOBversion, LALDict *LALparams)
double XLALSimIMRSpinAlignedEOBPeakFrequency(REAL8 m1SI, REAL8 m2SI, const REAL8 spin1z, const REAL8 spin2z, UINT4 SpinAlignedEOBversion)
This function returns the frequency at which the peak amplitude occurs in SEOBNRv(x)
int XLALSimInspiralPrecessingPolarizationWaveformHarmonic(COMPLEX16 *hplus, COMPLEX16 *hcross, REAL8 v, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhx, REAL8 lnhy, REAL8 lnhz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 dm, REAL8 eta, REAL8 v0, INT4 n, INT4 ampO)
Computes polarizations h+ and hx for a spinning, precessing binary when provided a single value of al...
int XLALSimInspiralGenerateFDModes(SphHarmFrequencySeries **hlm, LALDict *params, LALSimInspiralGenerator *generator)
Compute frequency-domain modes for a specific approximant.
int XLALSimInspiralPolarizationsFromSphHarmTimeSeries(REAL8TimeSeries **hp, REAL8TimeSeries **hc, SphHarmTimeSeries *hlms, REAL8 iota, REAL8 phiRef)
Compute the polarizations from all the -2 spin-weighted spherical harmonic modes stored in 'hlms'.
SphHarmTimeSeries * XLALSimInspiralChooseTDModes(UNUSED REAL8 phiRef, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 S1x, REAL8 S1y, REAL8 S1z, REAL8 S2x, REAL8 S2y, REAL8 S2z, REAL8 f_min, REAL8 f_ref, REAL8 distance, LALDict *params, int lmax, Approximant approximant)
Interface to compute a set of -2 spin-weighted spherical harmonic modes for a binary inspiral for a g...
int XLALSimInspiralPNPolarizationWaveforms(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8TimeSeries *V, REAL8TimeSeries *Phi, REAL8 v0, REAL8 m1, REAL8 m2, REAL8 r, REAL8 i, int ampO)
Given time series for a binary's orbital dynamical variables, construct the waveform polarizations h+...
COMPLEX16TimeSeries * XLALSimInspiralChooseTDMode(REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 f_ref, REAL8 r, REAL8 lambda1, REAL8 lambda2, LALSimInspiralWaveformFlags *waveFlags, LALSimInspiralTestGRParam *nonGRparams, int amplitudeO, int phaseO, int l, int m, Approximant approximant)
Interface to compute a single -2 spin-weighted spherical harmonic mode for a binary inspiral of any a...
LALSimInspiralGenerator * XLALSimInspiralChooseGenerator(Approximant approx, LALDict *params)
Returns LALSimInspiralGenerator object from approximant.
int XLALSimInspiralPNPolarizationWaveformsEccentric(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8TimeSeries *V, REAL8TimeSeries *Ecc, REAL8TimeSeries *U, REAL8TimeSeries *Phi, REAL8 m1, REAL8 m2, REAL8 r, REAL8 i, int ampO, int ph_O)
Given time series for a binary's orbital dynamical variables, computes the radial and angular orbital...
int XLALSimInspiralGenerateTDWaveform(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, LALDict *params, LALSimInspiralGenerator *generator)
Returns time-domain polarizations for a specific approximant.
void XLALSimInspiralParseDictionaryToChooseTDWaveform(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 *params)
Insert all the input arguments needed by XALSimInspiralChooseTDWaveform() into a laldictionary.
void XLALSimInspiralParseDictionaryToChooseTDModes(REAL8 *phiRef, REAL8 *deltaT, REAL8 *m1, REAL8 *m2, REAL8 *S1x, REAL8 *S1y, REAL8 *S1z, REAL8 *S2x, REAL8 *S2y, REAL8 *S2z, REAL8 *f_min, REAL8 *f_ref, REAL8 *distance, INT4 *lmax, LALDict *params)
Insert all the input arguments needed by XLALSimInspiralChooseTDModes() into a laldictionary.
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...
SphHarmTimeSeries * XLALSimInspiralTDModesFromPolarizations(REAL8 m1, REAL8 m2, REAL8 S1x, REAL8 S1y, REAL8 S1z, REAL8 S2x, REAL8 S2y, REAL8 S2z, REAL8 distance, 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...
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 XLALSimInspiralPolarizationsFromChooseFDModes(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 UNUSED longAscNodes, const REAL8 UNUSED eccentricity, const REAL8 UNUSED meanPerAno, const REAL8 deltaF, const REAL8 f_min, const REAL8 f_max, REAL8 f_ref, LALDict *LALparams, const Approximant approximant)
Function returning the Fourier domain polarizations for positive frequencies built from the individua...
void XLALSimInspiralParseDictionaryToChooseFDWaveform(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 *params)
Insert all the input arguments needed by XLALSimInspiralChooseFDWaveform() into a laldictionary.
const char * XLALSimInspiralGeneratorName(LALSimInspiralGenerator *generator)
Return approximant name from generator object.
void XLALSimInspiralParseDictionaryToChooseFDModes(REAL8 *m1, REAL8 *m2, REAL8 *S1x, REAL8 *S1y, REAL8 *S1z, REAL8 *S2x, REAL8 *S2y, REAL8 *S2z, REAL8 *deltaF, REAL8 *f_min, REAL8 *f_max, REAL8 *f_ref, REAL8 *phiRef, REAL8 *distance, REAL8 *inclination, LALDict *params)
Insert all the input arguments needed by XLALSimInspiralChooseFDModes() into a laldictionary.
int XLALSimInspiralPolarizationsFromSphHarmFrequencySeries(COMPLEX16FrequencySeries **hp, COMPLEX16FrequencySeries **hc, SphHarmFrequencySeries *hlms, REAL8 theta, REAL8 phi)
Return polarizations for positive frequencies built by summing the individual modes present in the in...
int XLALSimInspiralPNPolarizationWaveformsFromModes(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8TimeSeries *v, REAL8TimeSeries *phi, REAL8 v0, REAL8 m1, REAL8 m2, REAL8 r, REAL8 i, int O)
Given time series for a binary's orbital dynamical variables, construct the waveform polarizations h+...
int XLALSimInspiralPrecessingPolarizationWaveforms(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8TimeSeries *V, REAL8TimeSeries *Phi, REAL8TimeSeries *S1x, REAL8TimeSeries *S1y, REAL8TimeSeries *S1z, REAL8TimeSeries *S2x, REAL8TimeSeries *S2y, REAL8TimeSeries *S2z, REAL8TimeSeries *LNhatx, REAL8TimeSeries *LNhaty, REAL8TimeSeries *LNhatz, REAL8TimeSeries *E1x, REAL8TimeSeries *E1y, REAL8TimeSeries *E1z, REAL8 m1, REAL8 m2, REAL8 r, INT4 ampO)
Computes polarizations h+ and hx for a spinning, precessing binary when provided time series of all t...
SphHarmTimeSeries * XLALSimInspiralModesTD(REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 f_ref, REAL8 r, LALDict *LALpars, int lmax, Approximant approximant)
Interface to compute a conditioned set of -2 spin-weighted spherical harmonic modes for a binary insp...
int XLALSimInspiralTDFromTD(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)
Helper routines for XLALSimInspiralTD(): performs conditioning of a TD waveform.
int XLALSimInspiralTDFromFD(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)
Helper routines for XLALSimInspiralTD(): performs conditioning of a FD waveform and transforms it to ...
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...
LALSimInspiralGenerator * XLALCreateSimInspiralGenerator(const LALSimInspiralGenerator *generator, LALDict *params)
Create LALSimInspiralGenerator object.
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...
int XLALSimInspiralChooseWaveform(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 meanPerAno, const REAL8 deltaT, const REAL8 f_min, const REAL8 f_ref, LALDict *LALpars, const Approximant approximant)
int XLALSimInspiralGenerateTDModes(SphHarmTimeSeries **hlm, LALDict *params, LALSimInspiralGenerator *generator)
Compute time-domain modes for a specific approximant.
void XLALDestroySimInspiralGenerator(LALSimInspiralGenerator *generator)
Destroy LALSimInspiralGenerator object.
SphHarmFrequencySeries * XLALSimInspiralChooseFDModes(REAL8 m1, REAL8 m2, REAL8 S1x, REAL8 S1y, REAL8 S1z, REAL8 S2x, REAL8 S2y, REAL8 S2z, REAL8 deltaF, REAL8 f_min, REAL8 f_max, REAL8 f_ref, REAL8 phiRef, REAL8 distance, REAL8 inclination, LALDict *params, Approximant approximant)
Interface to compute a set of -2 spin-weighted spherical harmonic modes for a binary merger for a giv...
LALSimInspiralModesChoice
Enumerator for choosing which modes to include in IMR models.
#define LAL_SIM_INSPIRAL_FRAME_AXIS_DEFAULT
LALSimInspiralApplyTaper
Enumeration to specify the tapering method to apply to the waveform.
SpinSupport
FrequencyFunction
Enum of various frequency functions.
#define LAL_PN_MODE_L_MAX
SpinFreq
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.
AllowZeroMinFreq
LALPNOrder
Enum of possible values to use for post-Newtonian order.
TestGRaccept
@ LAL_SIM_INSPIRAL_MODES_CHOICE_3L
Inlude only l=3 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_2AND3AND4AND5L
Include l=2,3,4,5 modes.
@ LAL_SIM_INSPIRAL_MODES_CHOICE_2AND4L
Include l=2,4 modes.
@ LAL_SIM_INSPIRAL_TAPER_START
Taper the start of the waveform.
@ LAL_SIM_INSPIRAL_TAPER_STARTEND
Taper the start and the end of the waveform.
@ LAL_SIM_INSPIRAL_TAPER_NUM_OPTS
Number of elements in enum, useful for checking bounds.
@ LAL_SIM_INSPIRAL_TAPER_END
Taper the end of the waveform.
@ LAL_SIM_INSPIRAL_TAPER_NONE
No tapering.
@ LAL_SIM_INSPIRAL_CASEBYCASE_SPINSUPPORT
These approximant support fully precessing spins.
@ LAL_SIM_INSPIRAL_SINGLESPIN
These approximants cannot include spin terms.
@ LAL_SIM_INSPIRAL_SPINLESS
@ LAL_SIM_INSPIRAL_ALIGNEDSPIN
These approximants support a signle spin (by default that is the object 1)
@ LAL_SIM_INSPIRAL_PRECESSINGSPIN
These approximants can include spins aligned with L_N.
@ LAL_SIM_INSPIRAL_NUMSPINSUPPORT
This approximant (ExternalPython) has spin support determined by the external python module on a case...
@ fIMRPhenomBFinal
Final of IMRPhenomB.
@ fTEOBResumSFinal
Dominant ringdown frequency in TEOBResumS.
@ fIMRPhenomAFinal
Final frequency of IMRPhenomA.
@ fSEOBNRv5RD
Dominant ringdown frequency in SEOBNRv5_ROM.
@ fSEOBNRv2Peak
Frequency of the peak amplitude in SEOBNRv2.
@ fSEOBNRv4RD
Dominant ringdown frequency in SEOBNRv4.
@ fSEOBNRv1Peak
Frequency of the peak amplitude in SEOBNRv1.
@ fSchwarzISCO
Schwarzschild ISCO.
@ fSEOBNRv2RD
Dominant ringdown frequency in SEOBNRv2.
@ fEOBNRv2RD
Ringdown frequency of EOBNRv2.
@ fIMRPhenomCFinal
Final of IMRPhenomC.
@ fIMRPhenomDPeak
Frequency of the peak amplitude in IMRPhenomD.
@ fSEOBNRv5Peak
Frequency of the peak amplitude in SEOBNRv5_ROM.
@ fSEOBNRv4Peak
Frequency of the peak amplitude in SEOBNRv4.
@ fSEOBNRv1RD
Dominant ringdown frequency in SEOBNRv1.
@ fEOBNRv2HMRD
Ringdown frequency of highest harmonic in EOBNRv2HM.
@ LAL_SIM_INSPIRAL_SPINS_CASEBYCASE
These approximants have nonprecessing spins.
@ LAL_SIM_INSPIRAL_SPINS_FLOW
These approximants are parameterized by the spins at f_ref.
@ LAL_SIM_INSPIRAL_SPINS_F_REF
@ LAL_SIM_INSPIRAL_SPINS_NONPRECESSING
These approximants are parameterized by the spins at flow.
@ LAL_SIM_INSPIRAL_NUMSPINFREQ
These approximants (NR waveforms) have spins parameterized at different frequencies on a case-by-case...
@ 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.
@ EOB
Effective one-body waveform; Outputs a time-domain wave.
@ TaylorR2F4
A frequency domain model closely related to TaylorT4.
@ PadeT1
Time-domain P-approximant; Outputs a time-domain wave.
@ IMRPhenomFB
Frequency domain (non-precessing spins) inspiral-merger-ringdown templates of Ajith et al [Ajith_2009...
@ NumApproximants
Number of elements in enum, useful for checking bounds.
@ EOBNRv2HM
UNDOCUMENTED.
@ IMRPhenomFC
Frequency domain (non-precessing spins) inspiral-merger-ringdown templates of Santamaria et al [Santa...
@ SpinTaylorT4
Spinning case T4 models (lalsimulation's equivalent of SpinTaylorFrameless).
@ IMRPhenomPv3
Frequency domain (generic spins) inspiral-merger-ringdown templates of Hannam et al....
@ TaylorF2RedSpinTidal
TaylorF2 waveforms for non-precessing spins, defined in terms of a single (reduced-spin) parameter [A...
@ TaylorEt
UNDOCUMENTED.
@ SpinTaylorT5Fourier
Frequency domain (generic spins) inspiral only waveforms based on TaylorT5, , (the paper refers to S...
@ SEOBNRv4HM_PA
@ SEOBNRv2_ROM_DoubleSpin_HI
High resolution low-mass double-spin frequency domain reduced order model of spin-aligned EOBNR model...
@ SEOBNRv4_ROM_NRTidal
Low-mass double-spin frequency domain reduced order model of spin-aligned EOBNR model SEOBNRv4 [Bohe ...
@ FrameFile
The waveform contains arbitrary data read from a frame file.
@ IMRPhenomXAS_NRTidalv2
Spin non-precessing EOBNR model v4 with higher modes post-adiabatic dynamics (time domain) and TGR ri...
@ SEOBNRv2
Spin-aligned EOBNR model v2.
@ IMRPhenomTPHM
Time domain, precessing phenomenological IMR waveform model for L=2 sector ([arXiv: 20XY....
@ IMRPhenomP
Frequency domain (generic spins) inspiral-merger-ringdown templates of Hannam et al....
@ SEOBNRv4_ROM_NRTidalv2
based on NRTidalv2; https://arxiv.org/abs/1905.06011.
@ IMRPhenomXP
Frequency domain, precessing phenomenological IMR waveform model.
@ GeneratePPN
The time domain templates generated by LALGeneratePPNInspiral() in the inject package (equivalent to ...
@ BCVSpin
Detection template family of Buonanno, Chen and Vallisneri including spin effects ; Outputs a frequen...
@ SEOBNRv2_opt
Optimized Spin-aligned EOBNR model v2.
@ NumRel
UNDOCUMENTED.
@ SEOBNRv3_opt_rk4
USE RK4 Optimized Spin precessing EOBNR model v3.
@ IMRPhenomC
Frequency domain (non-precessing spins) inspiral-merger-ringdown templates of Santamaria et al [Santa...
@ SEOBNRv4HM_ROM
Low-mass double-spin frequency domain reduced order model of spin-aligned EOBNR model SEOBNRv4hm.
@ IMRPhenomPv2_NRTidal
Frequency domain tidal version of IMRPhenomPv2, using NRTidal framework from arXiv:1706....
@ SEOBNRv3_pert
Perturbed [m1 -> m1*(1+1e-15)] Spin precessing EOBNR model v3.
@ SEOBNRv1
Spin-aligned EOBNR model.
@ IMRPhenomT
@ Lackey_Tidal_2013_SEOBNRv2_ROM
Frequency domain tidal model based on reduced order model of SEOBNRv2.
@ NRHybSur3dq8
Time domain, aligned-spin, higher modes, hybridized.
@ HGimri
Time domain inspiral-merger-ringdown waveform for quasi-circular intermediate mass-ratio inspirals [H...
@ SEOBNRv4
Spin nonprecessing EOBNR model v4.
@ SEOBNRv3
Spin precessing EOBNR model v3.
@ EOBNRv2
UNDOCUMENTED.
@ IMRPhenomXO4a
Frequency domain, precessing with subdominant modes phenomenological IMR waveform model with NR-tuned...
@ TEOBResum_ROM
Time domain reduced order model of EOB with tidal effects.
@ IMRPhenomNSBH
NSBH Tidal model.
@ TaylorN
UNDOCUMENTED.
@ IMRPhenomXPHM
Frequency domain, precessing with subdominant modes phenomenological IMR waveform model.
@ IMRPhenomFA
Frequency domain (non-spinning) inspiral-merger-ringdown templates of Ajith et al [Ajith_2007kx] with...
@ IMRPhenomD
Frequency domain (non-precessing spins) inspiral-merger-ringdown templates of Husa et al,...
@ SpinQuadTaylor
Spinning case PN models with quadrupole-monopole and self-spin interaction.
@ IMRPhenomXHM
Frequency domain, non-precessing phenomenological IMR waveform model with subdominant modes ([arXiv:2...
@ EccentricFD
Frequency domain waveform in the SPA to describe low eccentricity systems.
@ SEOBNRv2_ROM_EffectiveSpin
Single-spin frequency domain reduced order model of spin-aligned EOBNR model SEOBNRv2.
@ FindChirpSP
The stationary phase templates implemented by FindChirpSPTemplate in the findchirp package (equivalen...
@ SEOBNRv4P
Spin precessing EOBNR model based on SEOBNRv4.
@ NRSur7dq4
q=4 extension of NRSur7dq2, arxiv: 1905.09300
@ IMRPhenomD_NRTidal
Uses arxiv:1706.02969 to upgrad IMRPhenomD to a tidal approximant.
@ TaylorF2RedSpin
TaylorF2 waveforms for non-precessing spins, defined in terms of a single (reduced-spin) parameter [A...
@ Eccentricity
UNDOCUMENTED.
@ EOBNR
UNDOCUMENTED.
@ PadeF1
Frequency-domain P-approximant (not yet implemented).
@ NR_hdf5
Time domain, NR waveform from HDF file.
@ SEOBNRv1_ROM_EffectiveSpin
Single-spin frequency domain reduced order model of spin-aligned EOBNR model SEOBNRv1 See [Purrer:201...
@ TaylorF2NLTides
The standard stationary phase approximation including a phenomenological model of nonlinear tidal eff...
@ IMRPhenomTP
Time domain, non-precessing phenomenological IMR waveform model with subdominant modes ([arXiv: 20XY....
@ IMRPhenomD_NRTidalv2
NRTidalv2; https://arxiv.org/abs/1905.06011.
@ IMRPhenomA
Time domain (non-spinning) inspiral-merger-ringdown waveforms generated from the inverse FFT of IMRPh...
@ IMRPhenomHM
Frequency domain with higher modes (non-precessing spins) inspiral-merger-ringdown templates,...
@ TaylorF2Ecc
The standard stationary phase approximation with eccentricity; Outputs a frequency-domain wave.
@ SEOBNRv4PHM
Spin precessing EOBNR model based on SEOBNRv4HM.
@ SpinTaylorT4Fourier
Frequency domain (generic spins) inspiral only waveforms based on TaylorT4, arXiv: 1408....
@ SpinDominatedWf
Time domain, inspiral only, 1 spin, precessing waveform, Tapai et al, arXiv: 1209....
@ AmpCorPPN
UNDOCUMENTED.
@ TaylorF1
The stationary phase approximation that correctly represents, in the Fourier domain,...
@ IMRPhenomPv2
Frequency domain (generic spins) inspiral-merger-ringdown templates of Hannam et al....
@ IMRPhenomPv2_NRTidalv2
Frequency domain tidal version; based on https://arxiv.org/abs/1905.06011.
@ NRSur7dq2
Time domain, fully precessing NR surrogate model with up to ell=4 modes, arxiv: 1705....
@ TaylorT3
Time domain Taylor approximant in which phase is explicitly given as a function of time; outputs a ti...
@ SpinTaylorF2
Spinning case F2 models (single spin only).
@ NRSur4d2s
@ EOBNRv2HM_ROM
Frequency domain reduced order model of model EOBNRv2HM, no spin but with higher modes.
@ IMRPhenomXAS
Frequency domain, non-precessing phenomenological IMR waveform model ([arXiv:2001....
@ EOBNRv2_ROM
Frequency domain reduced order model of model EOBNRv2HM, no spin neither higher modes.
@ SpinTaylorT5
Spinning case T5 models, which is a variant of the spinning version of the original TaylorT2 (see ) d...
@ PhenSpinTaylor
Inspiral part of the PhenSpinTaylorRD.
@ FindChirpPTF
UNDOCUMENTED.
@ TaylorT4
UNDOCUMENTED.
@ SEOBNRv4_ROM_NRTidalv2_NSBH
NSBH model based on SEOBNRv4_ROM_NRTidalv2.
@ SEOBNRv1_ROM_DoubleSpin
Double-spin frequency domain reduced order model of spin-aligned EOBNR model SEOBNRv1 See [Purrer:201...
@ SEOBNRv4HM
Spin nonprecessing EOBNR model v4 with higher modes, PhysRevD.98.084028 [arXiv:1803....
@ TaylorF2
The standard stationary phase approximation; Outputs a frequency-domain wave.
@ SEOBNRv4_ROM
Low-mass double-spin frequency domain reduced order model of spin-aligned EOBNR model SEOBNRv4.
@ SEOBNRv2_ROM_DoubleSpin
Double-spin frequency domain reduced order model of spin-aligned EOBNR model SEOBNRv2.
@ NumRelNinja2
The waveform contains REAL8 data generated by lalapps_fr_ninja from a file in the format described in...
@ IMRPhenomB
Time domain (non-precessing spins) inspiral-merger-ringdown waveforms generated from the inverse FFT ...
@ PhenSpinTaylorRD
Phenomenological waveforms, interpolating between a T4 spin-inspiral and the ringdown.
@ SpinTaylorFrameless
Spinning case PN models (replace SpinTaylor by removing the coordinate singularity)
@ SEOBNRv2T
Tidal EOB model.
@ IMRPhenomTHM
Time domain, non-precessing phenomenological IMR waveform model for the dominant (2,...
@ IMRPhenomPv3HM
Frequency domain (generic spins) inspiral-merger-ringdown templates of Khan et al.
@ BCV
Detection template family of Buonanno, Chen and Vallisneri ; Outputs a frequency-domain wave.
@ pSEOBNRv4HM_PA
Spin non-precessing EOBNR model v4 with higher modes post-adiabatic dynamics (time domain),...
@ ExternalPython
@ SEOBNRv4T
Tidal EOB model.
@ TaylorT1
Time domain Taylor approximant in which the energy and flux are both kept as Taylor expansions and a ...
@ SEOBNRv5_ROM
Time domain, precessing phenomenological IMR waveform model with subdominant modes ([arXiv: 20XY....
@ EccentricTD
Time domain Taylor T4 approximant including orbital eccentricity effects.
@ SpinTaylor
Spinning case PN models (should replace SpinTaylorT3 in the future)
@ SEOBNRv3_opt
Optimized Spin precessing EOBNR model v3.
@ SpinTaylorT1
Spinning case T1 models.
@ SpinTaylorT3
Spinning case T3 models.
@ IMRPhenomXP_NRTidalv2
Tidal extension of IMRPhenomXP based on [arXiv:1905.06011].
@ TEOBResumS
Resummed Spin-aligned Tidal EOB.
@ SEOBNRv5HM_ROM
External Python model.
@ TaylorT2
Time domain Taylor approximant in which the phase evolution is obtained by iteratively solving post-...
@ SEOBNRv4T_surrogate
Double-spin frequency domain surrogate model of spin-aligned tidal EOBNR model SEOBNRv4T.
@ SEOBNRv4_opt
Optimized Spin-aligned EOBNR model v4.
@ BCVC
UNDOCUMENTED.
@ LAL_SIM_INSPIRAL_DISALLOW_ZERO_FMIN
These approximants allow f_min=0, which means the full length of the available waveform is returned.
@ LAL_SIM_INSPIRAL_ALLOW_ZERO_FMIN
@ LAL_SIM_INSPIRAL_NUMZEROFMIN
These approximants do not allow f_min=0.
@ LAL_PNORDER_TWO_POINT_FIVE
2.5PN <==> O(v^5)
@ LAL_PNORDER_NUM_ORDER
Number of elements in enum, useful for checking bounds.
@ LAL_PNORDER_THREE
3PN <==> O(v^6)
@ LAL_PNORDER_TWO
2PN <==> O(v^4)
@ LAL_PNORDER_ONE
1PN <==> O(v^2)
@ LAL_PNORDER_PSEUDO_FOUR
pseudo-4PN tuning coefficients included, true 4PN terms currently unknown
@ LAL_PNORDER_THREE_POINT_FIVE
3.5PN <==> O(v^7)
@ LAL_PNORDER_HALF
0.5PN <==> O(v)
@ LAL_PNORDER_ONE_POINT_FIVE
1.5PN <==> O(v^3)
@ LAL_PNORDER_NEWTONIAN
Newtonain (leading) order.
@ LAL_SIM_INSPIRAL_CASEBYCASE_TESTGR_PARAMS
These approximants accept testGR params as input params.
@ LAL_SIM_INSPIRAL_NO_TESTGR_PARAMS
@ LAL_SIM_INSPIRAL_TESTGR_PARAMS
These approximants cannot accept testGR params as input params.
@ LAL_SIM_INSPIRAL_NUM_TESTGR_ACCEPT
This approximant (ExternalPython) accept testGR parameters depending on the external python module lo...
int XLALSimInspiralEccentricTDPNGenerator(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 fRef, REAL8 r, REAL8 i, REAL8 e_min, int amplitudeO, int phaseO)
Driver routine to compute the post-Newtonian inspiral waveform.
int XLALHGimriGenerator(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 r, REAL8 i, REAL8 S1z)
COMPLEX16TimeSeries * XLALCreateSimInspiralPNModeCOMPLEX16TimeSeries(REAL8TimeSeries *v, REAL8TimeSeries *phi, REAL8 v0, REAL8 m1, REAL8 m2, REAL8 r, int O, int l, int m)
Computes h(l,m) mode timeseries of spherical harmonic decomposition of the post-Newtonian inspiral wa...
int XLALSimInspiralSpinTaylorT5Fourier(COMPLEX16FrequencySeries **hplus, COMPLEX16FrequencySeries **hcross, REAL8 fMin, REAL8 fMax, REAL8 deltaF, INT4 kMax, REAL8 phiRef, REAL8 v0, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams, INT4 phaseO, INT4 amplitudeO, INT4 phiRefAtEnd)
Driver routine to compute a precessing post-Newtonian inspiral waveform in the Fourier domain with ph...
int XLALSimInspiralSpinTaylorT5(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, LALDict *LALparams)
Driver routine to compute a precessing post-Newtonian inspiral waveform with phasing computed from en...
int XLALSimInspiralInitialConditionsPrecessingApproxs(REAL8 *inc, REAL8 *S1x, REAL8 *S1y, REAL8 *S1z, REAL8 *S2x, REAL8 *S2y, REAL8 *S2z, const REAL8 inclIn, const REAL8 S1xIn, const REAL8 S1yIn, const REAL8 S1zIn, const REAL8 S2xIn, const REAL8 S2yIn, const REAL8 S2zIn, const REAL8 m1, const REAL8 m2, const REAL8 fRef, const REAL8 phiRef, LALSimInspiralFrameAxis axisChoice)
Function to specify the desired orientation of the spin components of a precessing binary.
int XLALSimInspiralSpinTaylorF2(COMPLEX16FrequencySeries **hplus_out, COMPLEX16FrequencySeries **hcross_out, REAL8 phi_ref, REAL8 deltaF, REAL8 m1_SI, REAL8 m2_SI, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, const REAL8 fStart, const REAL8 fEnd, const REAL8 f_ref, const REAL8 r, LALDict *moreParams, INT4 phaseO, INT4 amplitudeO)
Computes the stationary phase approximation to the Fourier transform of a chirp waveform with phase g...
int XLALSimInspiralSpinTaylorT4Fourier(COMPLEX16FrequencySeries **hplus, COMPLEX16FrequencySeries **hcross, REAL8 fMin, REAL8 fMax, REAL8 deltaF, INT4 kMax, REAL8 phiRef, REAL8 v0, REAL8 m1, REAL8 m2, REAL8 fStart, REAL8 fRef, REAL8 r, REAL8 s1x, REAL8 s1y, REAL8 s1z, REAL8 s2x, REAL8 s2y, REAL8 s2z, REAL8 lnhatx, REAL8 lnhaty, REAL8 lnhatz, REAL8 e1x, REAL8 e1y, REAL8 e1z, REAL8 lambda1, REAL8 lambda2, REAL8 quadparam1, REAL8 quadparam2, LALDict *LALparams, INT4 phaseO, INT4 amplitudeO, INT4 phiRefAtEnd)
Driver routine to compute a precessing post-Newtonian inspiral waveform in the Fourier domain with ph...
int XLALSimInspiralTaylorF2ReducedSpinTidal(COMPLEX16FrequencySeries **htilde, const REAL8 phic, const REAL8 deltaF, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 chi, const REAL8 lam1, const REAL8 lam2, const REAL8 fStart, const REAL8 fEnd, const REAL8 r, const INT4 phaseO, const INT4 ampO)
Generate the "reduced-spin templates" proposed in http://arxiv.org/abs/1107.1267 Add the tidal phase ...
int XLALSimInspiralTaylorF2ReducedSpin(COMPLEX16FrequencySeries **htilde, const REAL8 phic, const REAL8 deltaF, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 chi, const REAL8 fStart, const REAL8 fEnd, const REAL8 r, const INT4 phaseO, const INT4 ampO)
Driver routine to compute a non-precessing post-Newtonian inspiral waveform in the frequency domain,...
REAL8 XLALSimInspiralTaylorF2ReducedSpinComputeChi(const REAL8 m1, const REAL8 m2, const REAL8 s1z, const REAL8 s2z)
Compute the dimensionless, aligned-spin parameter chi as used in the TaylorF2RedSpin waveform.
int XLALSimInspiralTaylorEtPNGenerator(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phic, REAL8 x0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 r, REAL8 i, int amplitudeO, int phaseO)
Driver routine to compute the post-Newtonian inspiral waveform.
int XLALSimInspiralTaylorT1PNGenerator(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 fRef, REAL8 r, REAL8 i, REAL8 lambda1, REAL8 lambda2, LALSimInspiralTidalOrder tideO, int amplitudeO, int phaseO)
Driver routine to compute the post-Newtonian inspiral waveform.
int XLALSimInspiralTaylorF2(COMPLEX16FrequencySeries **htilde, const REAL8 phi_ref, const REAL8 deltaF, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 S1z, const REAL8 S2z, const REAL8 fStart, const REAL8 fEnd, const REAL8 f_ref, const REAL8 r, LALDict *LALpars)
Computes the stationary phase approximation to the Fourier transform of a chirp waveform.
int XLALSimInspiralTaylorT3PNGenerator(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 v0, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 f_min, REAL8 fRef, REAL8 r, REAL8 i, REAL8 lambda1, REAL8 lambda2, LALSimInspiralTidalOrder tideO, int amplitudeO, int phaseO)
Driver routine to compute the post-Newtonian inspiral waveform.
int XLALSimInspiralTaylorF2NLTides(COMPLEX16FrequencySeries **htilde, const REAL8 phi_ref, const REAL8 deltaF, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 S1z, const REAL8 S2z, const REAL8 fStart, const REAL8 fEnd, const REAL8 f_ref, const REAL8 r, LALDict *LALpars)
Computes the stationary phase approximation to the Fourier transform of a chirp waveform.
double XLALSimInspiralGetTestGRParam(const LALSimInspiralTestGRParam *parameter, const char *name)
Function that returns the value of the desired parameters in the test GR parameters linked list.
LALSimInspiralSpinOrder XLALSimInspiralGetSpinOrder(LALSimInspiralWaveformFlags *waveFlags)
Get the LALSimInspiralSpinOrder within a LALSimInspiralWaveformFlags struct, or LAL_SIM_INSPIRAL_SPIN...
LALSimInspiralModesChoice XLALSimInspiralGetModesChoice(LALSimInspiralWaveformFlags *waveFlags)
Get the LALSimInspiralModesChoice within a LALSimInspiralWaveformFlags struct, or LAL_SIM_INSPIRAL_MO...
bool XLALSimInspiralFrameAxisIsDefault(LALSimInspiralFrameAxis axisChoice)
Returns true if LALSimInspiralFrameAxis has default value returns false otherwise.
LALSimInspiralFrameAxis XLALSimInspiralGetFrameAxis(LALSimInspiralWaveformFlags *waveFlags)
Get the LALSimInspiralFrameAxis within a LALSimInspiralWaveformFlags struct, or LAL_SIM_INSPIRAL_FRAM...
bool XLALSimInspiralModesChoiceIsDefault(LALSimInspiralModesChoice modesChoice)
Returns true if LALSimInspiralModesChoice has default value returns false otherwise.
LALSimInspiralTidalOrder XLALSimInspiralGetTidalOrder(LALSimInspiralWaveformFlags *waveFlags)
Get the LALSimInspiralTidalOrder within a LALSimInspiralWaveformFlags struct, or LAL_SIM_INSPIRAL_TID...
bool XLALSimInspiralSpinOrderIsDefault(LALSimInspiralSpinOrder spinO)
Returns true if LALSimInspiralSpinOrder has default value returns false otherwise.
bool XLALSimInspiralWaveformFlagsIsDefaultOLD(LALSimInspiralWaveformFlags *waveFlags)
Returns true if waveFlags is non-NULL and all of its fields have default value; returns false otherwi...
char * XLALSimInspiralGetNumrelDataOLD(LALSimInspiralWaveformFlags *waveFlags)
Returns a deepcopy of the pointer of the numeraldata attribute of the waveFlags structure.
int XLALSimAddMode(REAL8TimeSeries *hplus, REAL8TimeSeries *hcross, COMPLEX16TimeSeries *hmode, REAL8 theta, REAL8 phi, int l, int m, int sym)
Multiplies a mode h(l,m) by a spin-2 weighted spherical harmonic to obtain hplus - i hcross,...
SphHarmTimeSeries * XLALSphHarmTimeSeriesAddMode(SphHarmTimeSeries *appended, const COMPLEX16TimeSeries *inmode, UINT4 l, INT4 m)
Prepend a node to a linked list of SphHarmTimeSeries, or create a new head.
COMPLEX16TimeSeries * XLALSphHarmTimeSeriesGetMode(SphHarmTimeSeries *ts, UINT4 l, INT4 m)
Get the time series of a waveform's (l,m) spherical harmonic mode from a SphHarmTimeSeries linked lis...
SphHarmTimeSeries * XLALResizeSphHarmTimeSeries(SphHarmTimeSeries *ts, int first, size_t length)
For every (l,m) node in the SphHarmTimeSeries linked list, call XLALResizeCOMPLEX16TimeSeries(ts->mod...
void XLALDestroySphHarmFrequencySeries(SphHarmFrequencySeries *ts)
Delete list from current pointer to the end of the list.
int XLALStringCaseCompare(const char *s1, const char *s2)
char char * XLALStringDuplicate(const char *s)
char * XLALStringCaseSubstring(const char *haystack, const char *needle)
static const INT4 r
static const INT4 m
void XLALDestroyREAL8FFTPlan(REAL8FFTPlan *plan)
REAL8FFTPlan * XLALCreateReverseREAL8FFTPlan(UINT4 size, int measurelvl)
COMPLEX16 XLALSpinWeightedSphericalHarmonic(REAL8 theta, REAL8 phi, int s, int l, int m)
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 XLALDestroyCOMPLEX16TimeSeries(COMPLEX16TimeSeries *series)
void XLALDestroyREAL8TimeSeries(REAL8TimeSeries *series)
REAL8TimeSeries * XLALShrinkREAL8TimeSeries(REAL8TimeSeries *series, size_t first, size_t length)
COMPLEX16TimeSeries * XLALCreateCOMPLEX16TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
const LALUnit lalStrainUnit
#define XLAL_ERROR_VOID(...)
#define XLAL_ERROR_VAL(val,...)
#define XLAL_ERROR_NULL(...)
#define XLAL_ERROR(...)
#define XLAL_CHECK(assertion,...)
#define XLAL_PRINT_WARNING(...)
#define XLAL_TRY(statement, errnum)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
int int XLALPrintWarning(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_CHECK_NULL(assertion,...)
#define XLAL_PRINT_DEPRECATION_WARNING(replacement)
XLAL_EBADLEN
XLAL_ENOMEM
XLAL_SUCCESS
XLAL_EFAULT
XLAL_EFUNC
XLAL_EDOM
XLAL_EINVAL
XLAL_FAILURE
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
LIGOTimeGPS * XLALGPSSetREAL8(LIGOTimeGPS *epoch, REAL8 t)
int XLALSimInspiralTransformPrecessingNewInitialConditions(REAL8 *incl, REAL8 *S1x, REAL8 *S1y, REAL8 *S1z, REAL8 *S2x, REAL8 *S2y, REAL8 *S2z, const REAL8 thetaJN, const REAL8 phiJL, const REAL8 theta1, const REAL8 theta2, const REAL8 phi12, const REAL8 chi1, const REAL8 chi2, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 fRef, const REAL8 phiRef)
Transform Precessing Parameters.
int XLALSimInspiralTransformPrecessingWvf2PE(REAL8 *thetaJN, REAL8 *phiJL, REAL8 *theta1, REAL8 *theta2, REAL8 *phi12, REAL8 *chi1, REAL8 *chi2, const REAL8 incl, const REAL8 S1x, const REAL8 S1y, const REAL8 S1z, const REAL8 S2x, const REAL8 S2y, const REAL8 S2z, const REAL8 m1, const REAL8 m2, const REAL8 fRef, const REAL8 phiRef)
inverse to XLALSimInspiralTransformPrecessingNewInitialConditions()
list mu
end
string approximant
COMPLEX16Sequence * data
COMPLEX16Sequence * data
COMPLEX16 * data
Linked list of any number of parameters for testing GR.
REAL8Sequence * data
LIGOTimeGPS epoch
REAL8 * data
struct tagSphHarmFrequencySeries * next
next pointer
COMPLEX16FrequencySeries * mode
The sequences of sampled data.
Structure to carry a collection of spherical harmonic modes in COMPLEX16 time series.
struct tagSphHarmTimeSeries * next
next pointer
COMPLEX16TimeSeries * mode
The sequences of sampled data.
Definition: burst.c:245
LIGOTimeGPS epoch
Definition: unicorn.c:20
double V
Definition: unicorn.c:25
double f_min
Definition: unicorn.c:22
double deltaT
Definition: unicorn.c:24
double f_max
Definition: unicorn.c:23