20#include <lal/LALSimIMR.h>
21#include <lal/SphericalHarmonics.h>
22#include <lal/Sequence.h>
25#include <lal/LALConstants.h>
26#include <lal/FrequencySeries.h>
27#include <lal/LALDatatypes.h>
28#include <lal/LALStdlib.h>
29#include <lal/XLALError.h>
53#define MIN(a,b) (((a)<(b))?(a):(b))
54#define MAX(a,b) (((a)>(b))?(a):(b))
134 REAL8 *alpha_offset_mprime,
135 REAL8 *epsilon_offset_mprime,
196 const REAL8 m1_SI_init = m1_SI;
197 const REAL8 m2_SI_init = m2_SI;
198 const REAL8 chi1z_init = chi1z;
199 const REAL8 chi2z_init = chi2z;
206 printf(
"fRef_In : %e\n",fRef_In);
207 printf(
"m1_SI : %e\n",m1_SI);
208 printf(
"m2_SI : %e\n",m2_SI);
209 printf(
"chi1L : %e\n",chi1z);
210 printf(
"chi2L : %e\n",chi2z);
211 printf(
"phiRef : %e\n",phiRef);
213 printf(
"Performing sanity checks...\n");
219 XLAL_CHECK(fRef_In >= 0,
XLAL_EFUNC,
"Error: fRef_In must be positive or set to 0 to ignore. \n");
225 XLAL_CHECK(distance > 0,
XLAL_EFUNC,
"Error: Distance must be positive and greater than 0. \n");
239 mass_ratio = m1_SI / m2_SI;
243 mass_ratio = m2_SI / m1_SI;
245 if(mass_ratio > 20.0 ) {
XLAL_PRINT_WARNING(
"Warning: Extrapolating outside of Numerical Relativity calibration domain. NNLO angles may become pathological at large mass ratios.\n"); }
246 if(mass_ratio > 1000. && fabs(mass_ratio - 1000) > 1
e-12) {
XLAL_ERROR(
XLAL_EDOM,
"ERROR: Model not valid at mass ratios beyond 1000.\n"); }
247 if(fabs(chi1z) > 0.99 || fabs(chi2z) > 0.99) {
XLAL_PRINT_WARNING(
"Warning: Extrapolating to extremal spins, model is not trusted.\n"); }
253 REAL8 fRef = (fRef_In == 0.0) ?
f_min : fRef_In;
256 LALDict *lalParams_aux;
258 if (lalParams == NULL)
267 printf(
"\n\n **** Initializing waveform struct... **** \n\n");
277 status =
IMRPhenomXSetWaveformVariables(pWF, m1_SI_init, m2_SI_init, chi1z_init, chi2z_init, deltaF, fRef, phiRef,
f_min,
f_max, distance, inclination, lalParams_aux,
PHENOMXDEBUG);
290 (fRef >= pWF->
fMin)&&(fRef <= pWF->f_max_prime),
292 "Error: f_min = %.2f <= fRef = %.2f < f_max = %.2f required when using tuned angles.\n",pWF->
fMin,fRef,pWF->
f_max_prime);
296 printf(
"\n\n **** Initializing precession struct... **** \n\n");
323 printf(
"\n\n **** Calling IMRPhenomXPHM_hplushcross... **** \n\n");
333 printf(
"\n\n **** Call to IMRPhenomXPHM_hplus_hcross complete. **** \n\n");
343 lastfreq = pWF->
fMax;
344 XLAL_PRINT_WARNING(
"The input f_max = %.2f Hz is larger than the internal cutoff of Mf=0.3 (%.2f Hz). Array will be filled with zeroes between these two frequencies.\n", pWF->
fMax, pWF->
f_max_prime);
350 size_t n_full =
NextPow2(lastfreq / deltaF) + 1;
351 size_t n = (*hptilde)->data->length;
355 XLAL_CHECK (*hptilde,
XLAL_ENOMEM,
"Failed to resize h_+ COMPLEX16FrequencySeries of length %zu (for internal fCut=%f) to new length %zu (for user-requested f_max=%f).", n, pWF->
fCut, n_full, pWF->
fMax );
359 XLAL_CHECK (*hctilde,
XLAL_ENOMEM,
"Failed to resize h_x COMPLEX16FrequencySeries of length %zu (for internal fCut=%f) to new length %zu (for user-requested f_max=%f).", n, pWF->
fCut, n_full, pWF->
fMax );
411 printf(
"fRef_In : %e\n",fRef_In);
412 printf(
"m1_SI : %e\n",m1_SI);
413 printf(
"m2_SI : %e\n",m2_SI);
414 printf(
"chi1L : %e\n",chi1z);
415 printf(
"chi2L : %e\n",chi2z);
416 printf(
"phiRef : %e\n",phiRef);
418 printf(
"Performing sanity checks...\n");
424 XLAL_CHECK(fRef_In >= 0,
XLAL_EFUNC,
"Error: fRef_In must be positive or set to 0 to ignore. \n");
430 XLAL_CHECK(distance > 0,
XLAL_EFUNC,
"Error: Distance must be positive and greater than 0. \n");
444 mass_ratio = m1_SI / m2_SI;
448 mass_ratio = m2_SI / m1_SI;
450 if(mass_ratio > 20.0 ) {
XLAL_PRINT_WARNING(
"Warning: Extrapolating outside of Numerical Relativity calibration domain. NNLO angles may become pathological at large mass ratios.\n"); }
451 if(mass_ratio > 1000. && fabs(mass_ratio - 1000) > 1
e-12) {
XLAL_ERROR(
XLAL_EDOM,
"ERROR: Model not valid at mass ratios beyond 1000."); }
452 if(fabs(chi1z) > 0.99 || fabs(chi2z) > 0.99) {
XLAL_PRINT_WARNING(
"Warning: Extrapolating to extremal spins, model is not trusted."); }
458 REAL8 fRef = (fRef_In == 0.0) ?
f_min : fRef_In;
461 LALDict *lalParams_aux;
463 if (lalParams == NULL)
472 printf(
"\n\n **** Initializing waveform struct... **** \n\n");
482 status =
IMRPhenomXSetWaveformVariables(pWF, m1_SI, m2_SI, chi1z, chi2z, deltaF, fRef, phiRef,
f_min,
f_max, distance, inclination, lalParams_aux,
PHENOMXDEBUG);
495 (fRef >= pWF->
fMin)&&(fRef <= pWF->f_max_prime),
497 "Error: f_min = %.2f <= fRef = %.2f < f_max = %.2f required when using tuned angles.\n",pWF->
fMin,fRef,pWF->
f_max_prime);
501 printf(
"\n\n **** Initializing precession struct... **** \n\n");
528 printf(
"\n\n **** Calling IMRPhenomXPHM_hplushcross_from_modes... **** \n\n");
536 printf(
"\n\n **** Call to IMRPhenomXPHM_from _modes complete. **** \n\n");
545 lastfreq = pWF->
fMax;
546 XLAL_PRINT_WARNING(
"The input f_max = %.2f Hz is larger than the internal cutoff of Mf=0.3 (%.2f Hz). Array will be filled with zeroes between these two frequencies.\n", pWF->
fMax, pWF->
f_max_prime);
552 size_t n_full =
NextPow2(lastfreq / deltaF) + 1;
553 size_t n = (*hptilde)->data->length;
557 XLAL_CHECK (*hptilde,
XLAL_ENOMEM,
"Failed to resize h_+ COMPLEX16FrequencySeries of length %zu (for internal fCut=%f) to new length %zu (for user-requested f_max=%f).", n, pWF->
fCut, n_full, pWF->
fMax );
561 XLAL_CHECK (*hctilde,
XLAL_ENOMEM,
"Failed to resize h_x COMPLEX16FrequencySeries of length %zu (for internal fCut=%f) to new length %zu (for user-requested f_max=%f).", n, pWF->
fCut, n_full, pWF->
fMax );
615 XLAL_CHECK(distance > 0,
XLAL_EFUNC,
"Error: Distance must be positive and greater than 0. \n");
629 mass_ratio = m1_SI / m2_SI;
633 mass_ratio = m2_SI / m1_SI;
635 if(mass_ratio > 20.0 ) {
XLAL_PRINT_INFO(
"Warning: Extrapolating outside of Numerical Relativity calibration domain."); }
636 if(mass_ratio > 1000. && fabs(mass_ratio - 1000) > 1
e-12) {
XLAL_ERROR(
XLAL_EDOM,
"ERROR: Model not valid at mass ratios beyond 1000."); }
637 if(fabs(chi1z) > 0.99 || fabs(chi2z) > 0.99) {
XLAL_PRINT_INFO(
"Warning: Extrapolating to extremal spins, model is not trusted."); }
643 REAL8 fRef = (fRef_In == 0.0) ? freqs->
data[0] : fRef_In;
651 (fRef >= f_min_In)&&(fRef <= f_max_In),
653 "Error: f_min = %.2f <= fRef = %.2f < f_max = %.2f required when using tuned angles.\n",f_min_In,fRef,f_max_In);
662 LALDict *lalParams_aux;
664 if (lalParams == NULL)
673 XLAL_PRINT_WARNING(
"Warning: Function is aimed for non-uniform frequency grid, switching off Multibanding.");
684 status =
IMRPhenomXSetWaveformVariables(pWF, m1_SI, m2_SI, chi1z, chi2z, 0.0, fRef, phiRef, f_min_In, f_max_In, distance, inclination, lalParams_aux,
DEBUG);
764 if (ModeArray == NULL)
788 size_t npts = (*hptilde)->data->length;
790 XLAL_CHECK (*hctilde,
XLAL_ENOMEM,
"Failed to allocated waveform COMPLEX16FrequencySeries of length %zu.", npts);
791 memset((*hctilde)->data->data, 0, npts *
sizeof(
COMPLEX16));
834 REAL8 Mf_RD_lm = 0.0;
836 if (IMRPhenomXPNRUseTunedAngles)
842 if (!hm_angle_spline)
859 if(isnan(betaPNR_ref) || isinf(betaPNR_ref))
XLAL_ERROR(
XLAL_EDOM,
"Error in %s: gsl_spline_eval for beta returned invalid value.\n",__func__);
864 "Error: IMRPhenomX_PNR_RemapThetaJSF failed in IMRPhenomX_PNR_GeneratePNRAngles.");
873 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
884 for (
UINT4 emmprime = 1; emmprime <= ell; emmprime++)
898 if((pWF->
q == 1) && (pWF->
chi1L == pWF->
chi2L) && (emmprime % 2 != 0))
916 printf(
"\n\n*********************************\n*Non-precessing Mode %i%i \n******************************\n",ell, emmprime);
923 sprintf(fileSpec,
"angles_hphc_%i%i.dat", ell, emmprime);
927 sprintf(fileSpec,
"angles_hphc_MB_%i%i.dat", ell, emmprime);
929 printf(
"\nOutput angle file: %s\r\n", fileSpec);
930 fileangle = fopen(fileSpec,
"w");
932 fprintf(fileangle,
"# q = %.16e m1 = %.16e m2 = %.16e chi1 = %.16e chi2 = %.16e lm = %i%i Mtot = %.16e distance = %.16e\n", pWF->
q, pWF->
m1, pWF->
m2, pWF->
chi1L, pWF->
chi2L, ell, emmprime, pWF->
Mtot, pWF->
distance/
LAL_PC_SI/1e6);
933 fprintf(fileangle,
"#fHz cexp_i_alpha(re im) cexp_i_epsilon(re im) cexp_i_betah(re im)\n");
944 if(ell % 2 !=0) minus1l = -1;
949 XLAL_CHECK(htildelm,
XLAL_ENOMEM,
"Failed to allocate COMPLEX16FrequencySeries of length %zu for f_max = %f, deltaF = %g.\n", npts, freqs_In->
data[freqs_In->
length - 1], pWF->
deltaF);
963 if (thresholdMB == 0){
964 if(ell == 2 && emmprime == 2)
976 if(ell==3 && emmprime==2){
999 if(ell==2 && emmprime==2)
1001 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
1023 && ((*hctilde)->data->length==htildelm->
data->
length),
1025 "Inconsistent lengths between frequency series htildelm (%d), hptilde (%d) and hctilde (%d).",
1026 htildelm->
data->
length, (*hptilde)->data->length, (*hctilde)->data->length
1043 printf(
"\n****************************************************************\n");
1044 printf(
"\n* NOT USING MBAND FOR ANGLES %i *\n", offset);
1045 printf(
"\n****************************************************************\n");
1052 printf(
"\n** We will not twist up the HM waveforms **\n");
1057 REAL8 Mf_high = 0.0;
1062 if (IMRPhenomXPNRUseTunedAngles)
1065 if((ell==2)&&(emmprime==2))
1086 double Mf = pWF->
M_sec * freqs->
data[idx];
1091 hlmcoprec = htildelm->
data->
data[idx + offset];
1098 hplus = 0.5 * hlmcoprec;
1099 hcross = -0.5 * I * hlmcoprec;
1111 if(IMRPhenomXPNRUseTunedAngles)
1125 if(ell == 2 && emmprime == 2 && AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
1129 hlmcoprec_antiSym = antiSym_amp->
data[idx]*cexp(I*antiSym_phi->
data[idx]);
1131 IMRPhenomXPHMTwistUp(Mf, hlmcoprec_antiSym, pWF, pPrec, ell, emmprime, &hplus_antiSym, &hcross_antiSym);
1133 hplus += hplus_antiSym;
1134 hcross += hcross_antiSym;
1138 (*hptilde)->data->data[idx + offset] += hplus;
1139 (*hctilde)->data->data[idx + offset] += hcross;
1144 (*hptilde)->data->data[idx + offset] += 0.0 + I*0.0;
1145 (*hctilde)->data->data[idx + offset] += 0.0 + I*0.0;
1149 if(IMRPhenomXPNRUseTunedAngles)
1151 gsl_interp_accel_reset(hm_angle_spline->
alpha_acc);
1152 gsl_interp_accel_reset(hm_angle_spline->
beta_acc);
1153 gsl_interp_accel_reset(hm_angle_spline->
gamma_acc);
1176 printf(
"\n****************************************************************\n");
1177 printf(
"\n* USING MBAND FOR ANGLES *\n");
1178 printf(
"\n****************************************************************\n");
1192 REAL8 epsilon = 0.0;
1202 if(IMRPhenomXPNRUseTunedAngles)
1204 REAL8 Mf_high = 0.0;
1208 if ((ell==2)&&(emmprime==2))
1226 FILE *fileangle0101;
1227 char fileSpec0101[40];
1229 sprintf(fileSpec0101,
"angles_pnr_MB_%i%i.dat", ell, emmprime);
1231 fileangle0101 = fopen(fileSpec0101,
"w");
1233 fprintf(fileangle0101,
"#Mf fHz alpha beta gamma\n");
1235 fprintf(fileangle0101,
"#Mf_low = %.16e\n",Mf_low);
1236 fprintf(fileangle0101,
"#Mf_high = %.16e\n",Mf_high);
1237 fprintf(fileangle0101,
"#Mf_RD_22 = %.16e\n",Mf_RD_22);
1238 fprintf(fileangle0101,
"#Mf_RD_lm = %.16e\n",Mf_RD_lm);
1242 for(
UINT4 j=0; j<lenCoarseArray; j++)
1249 f_mapped = (f_mapped > fCut) ? fCut : f_mapped;
1255 vbetah[j] =
beta / 2.0;
1259 fprintf(fileangle0101,
"%.16e\t%.16e\t%.16e\t%.16e\t%.16e\n",Mf,f_mapped,valpha[j],
beta,vepsilon[j]);
1266 fclose(fileangle0101);
1269 gsl_interp_accel_reset(hm_angle_spline->
alpha_acc);
1270 gsl_interp_accel_reset(hm_angle_spline->
beta_acc);
1271 gsl_interp_accel_reset(hm_angle_spline->
gamma_acc);
1285 for(
UINT4 j=0; j<lenCoarseArray; j++)
1293 vepsilon[j] = epsilon;
1294 vbetah[j] = acos(cBetah);
1306 for(
UINT4 j=0; j<lenCoarseArray; j++)
1310 const REAL8 v = cbrt (
LAL_PI * Mf * (2.0 / emmprime) );
1312 REAL8 cos_beta = 0.0;
1315 REAL8 alpha_offset_mprime = 0, epsilon_offset_mprime = 0;
1318 valpha[j] = vangles.
x - alpha_offset_mprime;
1319 vepsilon[j] = vangles.
y - epsilon_offset_mprime;
1320 cos_beta = vangles.
z;
1325 vbetah[j] = acos(cBetah);
1348 for(
UINT4 j=0; j<lenCoarseArray; j++)
1352 Mf = coarseFreqs->
data[j]*(2.0/emmprime);
1355 if(Mf< pPrec->ftrans_MRD)
1375 REAL8 dMf=(coarseFreqs->
data[j]-coarseFreqs->
data[j-1])* (2.0 / emmprime);
1376 REAL8 deltagamma=0.;
1406 if(fabs(cos_beta)>1)
1407 cos_beta=copysign(1.0, cos_beta);
1409 valpha[j]= alpha_i- alpha_offset_mprime;
1410 vepsilon[j] = -
gamma - epsilon_offset_mprime;
1415 vbetah[j] = acos(cBetah);
1427 XLAL_ERROR(
XLAL_EINVAL,
"Error: IMRPhenomXPrecVersion not recognized. Recommended default is 223.\n");
1438 UINT4 fine_count = 0, ratio;
1439 REAL8 Omega_alpha, Omega_epsilon, Omega_betah, Qalpha, Qepsilon, Qbetah;
1440 REAL8 Mfhere, Mfnext, evaldMf;
1441 Mfnext = coarseFreqs->
data[0];
1450 UINT4 length_fine_grid = iStop + 3;
1458 printf(
"\n\nLENGTHS fine grid estimate, coarseFreqs->length = %i %i\n", length_fine_grid, lenCoarseArray);
1459 printf(
"fine_count, htildelm->length, offset = %i %i %i\n", fine_count, htildelm->
data->
length, offset);
1463 for(
UINT4 j = 0; j<lenCoarseArray-1 && fine_count < iStop; j++)
1466 Mfnext = coarseFreqs->
data[j+1];
1468 Omega_alpha = (valpha[j + 1] - valpha[j]) /(Mfnext - Mfhere);
1469 Omega_epsilon = (vepsilon[j + 1] - vepsilon[j])/(Mfnext - Mfhere);
1470 Omega_betah = (vbetah[j + 1] - vbetah[j]) /(Mfnext - Mfhere);
1472 cexp_i_alpha[fine_count] = cexp(I*valpha[j]);
1473 cexp_i_epsilon[fine_count] = cexp(I*vepsilon[j]);
1474 cexp_i_betah[fine_count] = cexp(I*vbetah[j]);
1476 Qalpha = cexp(I*evaldMf*Omega_alpha);
1477 Qepsilon = cexp(I*evaldMf*Omega_epsilon);
1478 Qbetah = cexp(I*evaldMf*Omega_betah);
1482 REAL8 dratio = (Mfnext-Mfhere)/evaldMf;
1483 UINT4 ceil_ratio = ceil(dratio);
1484 UINT4 floor_ratio = floor(dratio);
1487 if(fabs(dratio-ceil_ratio) < fabs(dratio-floor_ratio))
1493 ratio = floor_ratio;
1498 for(
UINT4 kk = 1; kk < ratio && fine_count < iStop; kk++){
1499 cexp_i_alpha[fine_count] = Qalpha*cexp_i_alpha[fine_count-1];
1500 cexp_i_epsilon[fine_count] = Qepsilon*cexp_i_epsilon[fine_count-1];
1501 cexp_i_betah[fine_count] = Qbetah*cexp_i_betah[fine_count-1];
1512 printf(
"fine_count, htildelm->length, offset = %i %i %i\n", fine_count, htildelm->
data->
length, offset);
1517 for (
UINT4 idx = 0; idx < fine_count; idx++)
1519 double Mf = pWF->
M_sec * (idx + offset)*pWF->
deltaF;
1521 hlmcoprec = htildelm->
data->
data[idx + offset];
1535 if(ell == 2 && emmprime == 2 && AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
1539 hlmcoprec_antiSym = antiSym_amp->
data[idx] * cexp(I*antiSym_phi->
data[idx]);
1541 IMRPhenomXPHMTwistUp(Mf, hlmcoprec_antiSym, pWF, pPrec, ell, emmprime, &hplus_antiSym, &hcross_antiSym);
1543 hplus += hplus_antiSym;
1544 hcross += hcross_antiSym;
1547 (*hptilde)->data->data[idx + offset] += hplus ;
1548 (*hctilde)->data->data[idx + offset] += hcross ;
1565 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
1571 if (IMRPhenomXPNRUseTunedAngles){
1576 gsl_interp_accel_free(hm_angle_spline->
alpha_acc);
1577 gsl_interp_accel_free(hm_angle_spline->
beta_acc);
1578 gsl_interp_accel_free(hm_angle_spline->
gamma_acc);
1599 REAL8 cosPolFac, sinPolFac;
1604 for (
UINT4 i = offset;
i < (*hptilde)->data->length;
i++)
1606 PhPpolp = (*hptilde)->data->data[
i];
1607 PhPpolc = (*hctilde)->data->data[
i];
1609 (*hptilde)->data->data[
i] = cosPolFac * PhPpolp + sinPolFac * PhPpolc;
1610 (*hctilde)->data->data[
i] = cosPolFac * PhPpolc - sinPolFac * PhPpolp;
1629 gsl_interp_accel_free(pPrec->
alpha_acc);
1630 gsl_interp_accel_free(pPrec->
gamma_acc);
1637 printf(
"\n******Leaving IMRPhenomXPHM_hplushcross*****\n");
1675 if (ModeArray == NULL)
1688 size_t npts = (*hptilde)->data->length;
1690 XLAL_CHECK (*hctilde,
XLAL_ENOMEM,
"Failed to allocated waveform COMPLEX16FrequencySeries of length %zu.", npts);
1691 memset((*hctilde)->data->data, 0, npts *
sizeof(
COMPLEX16));
1704 for(
UINT4 ell = 2; ell <= 4; ell++)
1706 for(
INT4 emm = -1*ell; emm <= (
INT4)ell; emm++)
1709 printf(
"\n*****************************************************************\n");
1710 printf(
" Precessing mode (%i%i) ", ell, emm);
1711 printf(
"*******************************************************************\n");
1729 "Inconsistent lengths between frequency series hlmpos (%d), hlmneg (%d), hptilde (%d) and hctilde (%d).",
1744 (*hptilde)->data->data[
i] += 0.5*(hlmpos->
data->
data[
i] * Ylm + conj(hlmneg->
data->
data[
i]) * Ylmstar);
1745 (*hctilde)->data->data[
i] += I*0.5*(hlmpos->
data->
data[
i] * Ylm - conj(hlmneg->
data->
data[
i]) * Ylmstar);
1761 REAL8 cosPolFac, sinPolFac;
1766 for (
UINT4 i = offset;
i < (*hptilde)->data->length;
i++)
1768 PhPpolp = (*hptilde)->data->data[
i];
1769 PhPpolc = (*hctilde)->data->data[
i];
1771 (*hptilde)->data->data[
i] = cosPolFac * PhPpolp + sinPolFac * PhPpolc;
1772 (*hctilde)->data->data[
i] = cosPolFac * PhPpolc - sinPolFac * PhPpolp;
1789 gsl_interp_accel_free(pPrec->
alpha_acc);
1790 gsl_interp_accel_free(pPrec->
gamma_acc);
1797 printf(
"\n******Leaving IMRPhenomXPHM_hplushcross_from_modes*****\n");
1827 double epsilon = 0.0;
1829 double cBetah = 0.0;
1830 double sBetah = 0.0;
1832 COMPLEX16 cexp_i_alpha, cexp_i_epsilon = 1;
1866 const double v = cbrt (
LAL_PI * Mf * (2.0 / mprime) );
1868 double cos_beta = 0.0;
1871 REAL8 alpha_offset_mprime = 0, epsilon_offset_mprime = 0;
1874 alpha = vangles.
x - alpha_offset_mprime;
1875 epsilon = vangles.
y - epsilon_offset_mprime;
1876 cos_beta = vangles.
z;
1894 REAL8 Mfprime = Mf * (2.0 / mprime);
1898 if(Mfprime< pPrec->ftrans_MRD)
1904 XLAL_CHECK(success ==
XLAL_SUCCESS,
XLAL_EFUNC,
"%s: Failed to evaluate angles at f=%.7f for (l,m)=(%d,%d). Got alpha=%.4f,cosbeta=%.4f,gamma=%.4f.\n",__func__,
XLALSimIMRPhenomXUtilsMftoHz(Mfprime,pWF->
Mtot),
l,mprime,alpha_i,cos_beta,
gamma);
1920 REAL8 deltagamma=0.;
1943 alpha = alpha_i - alpha_offset_mprime;
1944 epsilon = -
gamma - epsilon_offset_mprime;
1956 XLAL_ERROR(
XLAL_EINVAL,
"Error. IMRPhenomXPrecVersion not recognized. Recommended default is 223.\n");
1961 cexp_i_alpha = cexp(+I*
alpha);
1965 cexp_i_epsilon = cexp(+I*epsilon);
1978 REAL8 cBetah2 = cBetah * cBetah;
1979 REAL8 cBetah3 = cBetah * cBetah2;
1980 REAL8 cBetah4 = cBetah * cBetah3;
1981 REAL8 cBetah5 = cBetah * cBetah4;
1982 REAL8 cBetah6 = cBetah * cBetah5;
1983 REAL8 cBetah7 = cBetah * cBetah6;
1984 REAL8 cBetah8 = cBetah * cBetah7;
1986 REAL8 sBetah2 = sBetah * sBetah;
1987 REAL8 sBetah3 = sBetah * sBetah2;
1988 REAL8 sBetah4 = sBetah * sBetah3;
1989 REAL8 sBetah5 = sBetah * sBetah4;
1990 REAL8 sBetah6 = sBetah * sBetah5;
1991 REAL8 sBetah7 = sBetah * sBetah6;
1992 REAL8 sBetah8 = sBetah * sBetah7;
2003 if (
l == 2 && mprime == 2){
2006 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2008 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2009 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2011 COMPLEX16 cexp_im_alpha_l2[5] = {cexp_m2i_alpha, cexp_mi_alpha, 1.0, cexp_i_alpha, cexp_2i_alpha};
2016 COMPLEX16 d22[5] = {sBetah4, 2.0*cBetah*sBetah3, pPrec->
sqrt6*sBetah2*cBetah2, 2.0*cBetah3*sBetah, cBetah4};
2018 COMPLEX16 d2m2[5] = {d22[4], -d22[3], d22[2], -d22[1], d22[0]};
2022 for(
int m=-2;
m<=2;
m++)
2025 COMPLEX16 A2m2emm = cexp_im_alpha_l2[-
m+2] * d2m2[
m+2] * Y2mA[
m+2];
2026 COMPLEX16 A22emmstar = cexp_im_alpha_l2[
m+2] * d22[
m+2] * conj(Y2mA[
m+2]);
2028 hp_sum += A2m2emm + polarizationSymmetry * A22emmstar;
2029 hc_sum += I*(A2m2emm - polarizationSymmetry * A22emmstar);
2033 if (
l == 2 && mprime == 1){
2036 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2038 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2039 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2041 COMPLEX16 cexp_im_alpha_l2[5] = {cexp_m2i_alpha, cexp_mi_alpha, 1.0, cexp_i_alpha, cexp_2i_alpha};
2046 COMPLEX16 d21[5] = {2.0*cBetah*sBetah3, 3.0*cBetah2*sBetah2 - sBetah4, pPrec->
sqrt6*(cBetah3*sBetah - cBetah*sBetah3), cBetah2*(cBetah2 - 3.0*sBetah2), -2.0*cBetah3*sBetah};
2048 COMPLEX16 d2m1[5] = {-d21[4], d21[3], -d21[2], d21[1], -d21[0]};
2051 for(
int m=-2;
m<=2;
m++)
2054 COMPLEX16 A2m1emm = cexp_im_alpha_l2[-
m+2] * d2m1[
m+2] * Y2mA[
m+2];
2055 COMPLEX16 A21emmstar = cexp_im_alpha_l2[
m+2] * d21[
m+2] * conj(Y2mA[
m+2]);
2056 hp_sum += A2m1emm + A21emmstar;
2057 hc_sum += I*(A2m1emm - A21emmstar);
2063 if (
l == 3 && mprime == 3){
2066 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2067 COMPLEX16 cexp_3i_alpha = cexp_i_alpha * cexp_2i_alpha;
2069 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2070 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2071 COMPLEX16 cexp_m3i_alpha = cexp_mi_alpha * cexp_m2i_alpha;
2073 COMPLEX16 cexp_im_alpha_l3[7] = {cexp_m3i_alpha, cexp_m2i_alpha, cexp_mi_alpha, 1.0, cexp_i_alpha, cexp_2i_alpha, cexp_3i_alpha};
2078 COMPLEX16 d33[7] = {sBetah6, pPrec->
sqrt6*cBetah*sBetah5, pPrec->
sqrt15*cBetah2*sBetah4, 2.0*pPrec->
sqrt5*cBetah3*sBetah3, pPrec->
sqrt15*cBetah4*sBetah2, pPrec->
sqrt6*cBetah5*sBetah, cBetah6};
2080 COMPLEX16 d3m3[7] = {d33[6], -d33[5], d33[4], -d33[3], d33[2], -d33[1], d33[0]};
2082 for(
int m=-3;
m<=3;
m++)
2085 COMPLEX16 A3m3emm = cexp_im_alpha_l3[-
m+3] * d3m3[
m+3] * Y3mA[
m+3];
2086 COMPLEX16 A33emmstar = cexp_im_alpha_l3[
m+3] * d33[
m+3] * conj(Y3mA[
m+3]);
2087 hp_sum += A3m3emm - A33emmstar;
2088 hc_sum += I*(A3m3emm + A33emmstar);
2093 if (
l == 3 && mprime == 2){
2096 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2097 COMPLEX16 cexp_3i_alpha = cexp_i_alpha * cexp_2i_alpha;
2099 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2100 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2101 COMPLEX16 cexp_m3i_alpha = cexp_mi_alpha * cexp_m2i_alpha;
2103 COMPLEX16 cexp_im_alpha_l3[7] = {cexp_m3i_alpha, cexp_m2i_alpha, cexp_mi_alpha, 1.0, cexp_i_alpha, cexp_2i_alpha, cexp_3i_alpha};
2108 COMPLEX16 d32[7] = {pPrec->
sqrt6*cBetah*sBetah5, sBetah4*(5.0*cBetah2 - sBetah2), pPrec->
sqrt10*sBetah3*(2.0*cBetah3 - cBetah*sBetah2), pPrec->
sqrt30*cBetah2*(cBetah2 - sBetah2)*sBetah2, pPrec->
sqrt10*cBetah3*(cBetah2*sBetah - 2.0*sBetah3), cBetah4*(cBetah2 - 5.0*sBetah2), -1.0*pPrec->
sqrt6*cBetah5*sBetah};
2110 COMPLEX16 d3m2[7] = {-d32[6], d32[5], -d32[4], d32[3], -d32[2], d32[1], -d32[0]};
2113 for(
int m=-3;
m<=3;
m++)
2116 COMPLEX16 A3m2emm = cexp_im_alpha_l3[-
m+3] * d3m2[
m+3] * Y3mA[
m+3];
2117 COMPLEX16 A32emmstar = cexp_im_alpha_l3[
m+3] * d32[
m+3] * conj(Y3mA[
m+3]);
2118 hp_sum += A3m2emm - A32emmstar;
2119 hc_sum += I*(A3m2emm + A32emmstar);
2125 if (
l == 4 && mprime == 4){
2128 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2129 COMPLEX16 cexp_3i_alpha = cexp_i_alpha * cexp_2i_alpha;
2130 COMPLEX16 cexp_4i_alpha = cexp_i_alpha * cexp_3i_alpha;
2132 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2133 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2134 COMPLEX16 cexp_m3i_alpha = cexp_mi_alpha * cexp_m2i_alpha;
2135 COMPLEX16 cexp_m4i_alpha = cexp_mi_alpha * cexp_m3i_alpha;
2137 COMPLEX16 cexp_im_alpha_l4[9] = {cexp_m4i_alpha, cexp_m3i_alpha, cexp_m2i_alpha, cexp_mi_alpha, 1.0, cexp_i_alpha, cexp_2i_alpha, cexp_3i_alpha, cexp_4i_alpha};
2142 COMPLEX16 d44[9] = {sBetah8, 2.0*pPrec->
sqrt2*cBetah*sBetah7, 2.0*pPrec->
sqrt7*cBetah2*sBetah6, 2.0*pPrec->
sqrt14*cBetah3*sBetah5, pPrec->
sqrt70*cBetah4*sBetah4, 2.0*pPrec->
sqrt14*cBetah5*sBetah3, 2.0*pPrec->
sqrt7*cBetah6*sBetah2, 2.0*pPrec->
sqrt2*cBetah7*sBetah, cBetah8};
2144 COMPLEX16 d4m4[9] = {d44[8], -d44[7], d44[6], -d44[5], d44[4], -d44[3], d44[2], -d44[1], d44[0]};
2146 for(
int m=-4;
m<=4;
m++)
2149 COMPLEX16 A4m4emm = cexp_im_alpha_l4[-
m+4] * d4m4[
m+4] * Y4mA[
m+4];
2150 COMPLEX16 A44emmstar = cexp_im_alpha_l4[
m+4] * d44[
m+4] * conj(Y4mA[
m+4]);
2151 hp_sum += A4m4emm + A44emmstar;
2152 hc_sum += I*(A4m4emm - A44emmstar);
2157 if (
l == 4 && mprime == 3){
2160 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2161 COMPLEX16 cexp_3i_alpha = cexp_i_alpha * cexp_2i_alpha;
2162 COMPLEX16 cexp_4i_alpha = cexp_i_alpha * cexp_3i_alpha;
2164 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2165 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2166 COMPLEX16 cexp_m3i_alpha = cexp_mi_alpha * cexp_m2i_alpha;
2167 COMPLEX16 cexp_m4i_alpha = cexp_mi_alpha * cexp_m3i_alpha;
2169 COMPLEX16 cexp_im_alpha_l4[9] = {cexp_m4i_alpha, cexp_m3i_alpha, cexp_m2i_alpha, cexp_mi_alpha, 1.0, cexp_i_alpha, cexp_2i_alpha, cexp_3i_alpha, cexp_4i_alpha};
2174 COMPLEX16 d43[9] = {2*pPrec->
sqrt2*cBetah*sBetah7, 7*cBetah2*sBetah6-sBetah8, pPrec->
sqrt14*(3*cBetah3*sBetah5-cBetah*sBetah7), pPrec->
sqrt7*(5*cBetah4*sBetah4-3*cBetah2*sBetah6), 2*5.916079783099616*(cBetah5*sBetah3-cBetah3*sBetah5), pPrec->
sqrt7*(3*cBetah6*sBetah2-5*cBetah4*sBetah4), pPrec->
sqrt14*(cBetah7*sBetah-3*cBetah5*sBetah3), cBetah8-7*cBetah6*sBetah2, -2.*pPrec->
sqrt2*cBetah7*sBetah};
2176 COMPLEX16 d4m3[9] = {-d43[8], d43[7], -d43[6], d43[5], -d43[4], d43[3], -d43[2], d43[1], -d43[0]};
2178 for(
int m=-4;
m<=4;
m++)
2181 COMPLEX16 A4m3emm = cexp_im_alpha_l4[-
m+4] * d4m3[
m+4] * Y4mA[
m+4];
2182 COMPLEX16 A43emmstar = cexp_im_alpha_l4[
m+4] * d43[
m+4] * conj(Y4mA[
m+4]);
2183 hp_sum += A4m3emm + A43emmstar;
2184 hc_sum += I*(A4m3emm - A43emmstar);
2192 eps_phase_hP_lmprime = cexp(-1.*mprime*I*epsilon) * hlmprime / 2.0;
2195 COMPLEX16 exp_imprime_epsilon = cexp_i_epsilon;
2198 exp_imprime_epsilon *= cexp_i_epsilon;
2200 eps_phase_hP_lmprime = 1./exp_imprime_epsilon * hlmprime / 2.0;
2205 *hp += eps_phase_hP_lmprime * hp_sum;
2206 *hc += eps_phase_hP_lmprime * hc_sum;
2215 sprintf(fileSpec,
"angles_hphc_%i%i.dat",
l, mprime);
2219 sprintf(fileSpec,
"angles_hphc_MB_%i%i.dat",
l, mprime);
2221 fileangle = fopen(fileSpec,
"a");
2310 const REAL8 distance,
2311 const REAL8 inclination,
2316 const REAL8 fRef_In,
2328 printf(
"fRef_In : %e\n",fRef_In);
2329 printf(
"m1_SI : %e\n",m1_SI);
2330 printf(
"m2_SI : %e\n",m2_SI);
2331 printf(
"chi1_l : %e\n",chi1z);
2332 printf(
"chi2_l : %e\n",chi2z);
2333 printf(
"phiRef : %e\n",phiRef);
2335 printf(
"Performing sanity checks...\n");
2341 XLAL_CHECK(fRef_In >= 0,
XLAL_EFUNC,
"Error: fRef_In must be positive or set to 0 to ignore. \n");
2347 XLAL_CHECK(distance > 0,
XLAL_EFUNC,
"Error: Distance must be positive and greater than 0. \n");
2361 mass_ratio = m1_SI / m2_SI;
2365 mass_ratio = m2_SI / m1_SI;
2367 if(mass_ratio > 20.0 ) {
XLAL_PRINT_WARNING(
"Warning: Extrapolating outside of Numerical Relativity calibration domain. NNLO angles may become pathological at large mass ratios.\n"); }
2368 if(mass_ratio > 1000. && fabs(mass_ratio - 1000) > 1
e-12) {
XLAL_ERROR(
XLAL_EDOM,
"ERROR: Model not valid at mass ratios beyond 1000.\n"); }
2369 if(fabs(chi1z) > 0.99 || fabs(chi2z) > 0.99) {
XLAL_PRINT_WARNING(
"Warning: Extrapolating to extremal spins, model is not trusted.\n"); }
2372 REAL8 fRef = (fRef_In == 0.0) ?
f_min : fRef_In;
2375 LALDict *lalParams_aux;
2377 if (lalParams == NULL)
2388 printf(
"\n\n **** Initializing waveform struct... **** \n\n");
2399 status =
IMRPhenomXSetWaveformVariables(pWF, m1_SI, m2_SI, chi1z, chi2z, deltaF, fRef, phiRef,
f_min,
f_max, distance, inclination, lalParams_aux,
PHENOMXDEBUG);
2412 printf(
"\n\n **** Initializing precession struct... **** \n\n");
2421 if(pflag==310||pflag==311||pflag==320||pflag==321||pflag==330){
2454 XLAL_PRINT_WARNING(
"The L0Frame option only works near the AS limit, it should not be used otherwise.");
2474 printf(
"\n\n **** Calling IMRPhenomXPHM_OneMode... **** \n\n");
2497 for(
UINT4 i = 0;
i<(*hlmpos)->data->length;
i++)
2499 (*hlmpos)->data->data[
i] *= shiftpos;
2500 (*hlmneg)->data->data[
i] *= shiftneg;
2508 printf(
"\n\n **** Call to IMRPhenomXPHM_OneMode complete. **** \n\n");
2517 lastfreq = pWF->
fMax;
2518 XLAL_PRINT_WARNING(
"The input f_max = %.2f Hz is larger than the internal cutoff of Mf=0.3 (%.2f Hz). Array will be filled with zeroes between these two frequencies.\n", pWF->
fMax, pWF->
f_max_prime);
2524 size_t n_full =
NextPow2(lastfreq / deltaF) + 1;
2525 size_t n = (*hlmpos)->data->length;
2529 XLAL_CHECK (*hlmpos,
XLAL_ENOMEM,
"Failed to resize hlmpos COMPLEX16FrequencySeries of length %zu (for internal fCut=%f) to new length %zu (for user-requested f_max=%f).", n, pWF->
fCut, n_full, pWF->
fMax );
2533 XLAL_CHECK (*hlmneg,
XLAL_ENOMEM,
"Failed to resize hlmneg COMPLEX16FrequencySeries of length %zu (for internal fCut=%f) to new length %zu (for user-requested f_max=%f).", n, pWF->
fCut, n_full, pWF->
fMax );
2545 gsl_interp_accel_free(pPrec->
alpha_acc);
2546 gsl_interp_accel_free(pPrec->
gamma_acc);
2580 const REAL8 distance,
2581 const REAL8 inclination,
2583 const REAL8 fRef_In,
2595 printf(
"fRef_In : %e\n",fRef_In);
2596 printf(
"m1_SI : %e\n",m1_SI);
2597 printf(
"m2_SI : %e\n",m2_SI);
2598 printf(
"chi1_l : %e\n",chi1z);
2599 printf(
"chi2_l : %e\n",chi2z);
2600 printf(
"phiRef : %e\n",phiRef);
2602 printf(
"Performing sanity checks...\n");
2608 XLAL_CHECK(fRef_In >= 0,
XLAL_EFUNC,
"Error: fRef_In must be positive or set to 0 to ignore. \n");
2611 XLAL_CHECK(distance > 0,
XLAL_EFUNC,
"Error: Distance must be positive and greater than 0. \n");
2628 mass_ratio = m1_SI / m2_SI;
2632 mass_ratio = m2_SI / m1_SI;
2634 if(mass_ratio > 20.0 ) {
XLAL_PRINT_WARNING(
"Warning: Extrapolating outside of Numerical Relativity calibration domain. NNLO angles may become pathological at large mass ratios.\n"); }
2635 if(mass_ratio > 1000. && fabs(mass_ratio - 1000) > 1
e-12) {
XLAL_ERROR(
XLAL_EDOM,
"ERROR: Model not valid at mass ratios beyond 1000.\n"); }
2636 if(fabs(chi1z) > 0.99 || fabs(chi2z) > 0.99) {
XLAL_PRINT_WARNING(
"Warning: Extrapolating to extremal spins, model is not trusted.\n"); }
2639 REAL8 fRef = (fRef_In == 0.0) ?
f_min : fRef_In;
2642 LALDict *lalParams_aux;
2644 if (lalParams == NULL)
2656 printf(
"\n\n **** Initializing waveform struct... **** \n\n");
2667 status =
IMRPhenomXSetWaveformVariables(pWF, m1_SI, m2_SI, chi1z, chi2z, 0.0, fRef, phiRef,
f_min,
f_max, distance, inclination, lalParams_aux,
PHENOMXDEBUG);
2672 printf(
"\n\n **** Initializing precession struct... **** \n\n");
2681 if(pflag==310||pflag==311||pflag==320||pflag==321||pflag==330){
2718 XLAL_PRINT_WARNING(
"The L0Frame option only works near the AS limit, it should not be used otherwise.");
2737 printf(
"\n\n **** Calling IMRPhenomXPHM_OneMode... **** \n\n");
2763 for(
UINT4 i = 0;
i<(*hlmpos)->data->length;
i++)
2765 (*hlmpos)->data->data[
i] *= shiftpos;
2766 (*hlmneg)->data->data[
i] *= shiftneg;
2774 printf(
"\n\n **** Call to IMRPhenomXPHM_OneMode complete. **** \n\n");
2788 gsl_interp_accel_free(pPrec->
alpha_acc);
2789 gsl_interp_accel_free(pPrec->
gamma_acc);
2835 if (ModeArray == NULL)
2841 bool mode_arrays_consistent =
false;
2843 while (mode_arrays_consistent ==
false && emm<=(
INT4)ell){
2845 mode_arrays_consistent =
true;
2849 if(mode_arrays_consistent ==
false){
2850 XLAL_ERROR(
XLAL_EDOM,
"ModeArrays are not consistent. The (%i,%i) mode in the inertial J-frame requires at least one mode with l=%i in the ModeArray (L-frame) option.\n", ell, emm-1, ell);
2860 size_t npts = (*hlmpos)->data->length;
2862 XLAL_CHECK (*hlmneg,
XLAL_ENOMEM,
"Failed to allocated waveform COMPLEX16FrequencySeries of length %zu.", npts);
2863 memset((*hlmneg)->data->data, 0, npts *
sizeof(
COMPLEX16));
2880 UINT4 n_coprec_modes = 0;
2888 REAL8 Mf_RD_lm = 0.0;
2890 if (IMRPhenomXPNRUseTunedAngles){
2894 if (!hm_angle_spline)
2915 "Error: IMRPhenomX_PNR_RemapThetaJSF failed in IMRPhenomX_PNR_GeneratePNRAngles.");
2922 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
2930 for (
UINT4 emmprime = 1; emmprime <= ell; emmprime++)
2951 printf(
"\n*************************************************\n Non-precessing Mode %i%i\n************************************",ell, emmprime);
2958 if (thresholdMB == 0){
2959 if(ell == 2 && emmprime == 2)
2971 if(ell==3 && emmprime==2){
2993 if(ell==2 && emmprime==2)
2995 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
3007 && ((*hlmneg)->data->length==htildelm->
data->
length),
3009 "Inconsistent lengths between frequency series htildelm (%d), hlmpos (%d) and hlmneg (%d).",
3010 htildelm->
data->
length, (*hlmpos)->data->length, (*hlmneg)->data->length
3014 if((pWF->
q == 1) && (pWF->
chi1L == pWF->
chi2L) && (emmprime % 2 != 0))
3032 hlmcoprec = htildelm->
data->
data[idx + offset];
3033 if(
m < 0) (*hlmpos)->data->data[idx + offset] = hlmcoprec;
3034 if(
m > 0) (*hlmneg)->data->data[idx + offset] = hlmcoprec;
3040 REAL8 Mf_high = 0.0;
3045 if (IMRPhenomXPNRUseTunedAngles){
3047 if((ell==2)&&(emmprime==2))
3067 hlmcoprec = htildelm->
data->
data[idx + offset];
3070 if(ell == 2 && emmprime == 2 && AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
3072 hlmcoprec_antiSym = antiSym_amp->
data[idx]*cexp(I*antiSym_phi->
data[idx]);
3078 if(IMRPhenomXPNRUseTunedAngles)
3092 (*hlmpos)->data->data[idx + offset] += hlm->
data[0];
3093 (*hlmneg)->data->data[idx + offset] += hlm->
data[1];
3097 if(IMRPhenomXPNRUseTunedAngles)
3099 gsl_interp_accel_reset(hm_angle_spline->
alpha_acc);
3100 gsl_interp_accel_reset(hm_angle_spline->
beta_acc);
3101 gsl_interp_accel_reset(hm_angle_spline->
gamma_acc);
3108 if (IMRPhenomXPNRUseTunedAngles){
3113 gsl_interp_accel_free(hm_angle_spline->
alpha_acc);
3114 gsl_interp_accel_free(hm_angle_spline->
beta_acc);
3115 gsl_interp_accel_free(hm_angle_spline->
gamma_acc);
3121 if(n_coprec_modes == 0)
3123 XLAL_PRINT_ERROR(
"For computing the mode (%i,%i) in the inertial J-frame we need at least one l=%i mode activated in the co-precessing L-frame. \nConsider activate some l=%i modes in L-frame with the ModeArray option of the LAL dictionary. \nWe filled the (%i,%i) mode with zeroes." , ell,
m, ell, ell, ell,
m);
3133if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
3141printf(
"\n******Leaving IMRPhenomXPHM_OneMode*****\n");
3170 double epsilon = 0.0;
3172 double cBetah = 0.0;
3173 double sBetah = 0.0;
3205 const double v = cbrt(
LAL_PI * Mf * (2.0/mprime) );
3207 double cos_beta = 0.0;
3209 REAL8 alpha_offset_mprime = 0, epsilon_offset_mprime = 0;
3212 alpha = vangles.
x - alpha_offset_mprime;
3213 epsilon = vangles.
y - epsilon_offset_mprime;
3214 cos_beta = vangles.
z;
3236 REAL8 Mfprime = Mf * (2.0 / mprime);
3238 if(Mfprime< pPrec->ftrans_MRD)
3244 XLAL_CHECK(success ==
XLAL_SUCCESS,
XLAL_EFUNC,
"%s: Failed to interpolate angles at f=%.7f, got alpha_i=%.4f, cosbeta=%.4f, gamma=%.4f: \n",__func__,
XLALSimIMRPhenomXUtilsMftoHz(Mfprime,pWF->
Mtot),alpha_i,cos_beta,
gamma);
3262 REAL8 deltagamma=0.;
3283 alpha = alpha_i- alpha_offset_mprime;
3284 epsilon = -
gamma - epsilon_offset_mprime;
3294 XLAL_ERROR(
XLAL_EINVAL,
"Error. IMRPhenomXPrecVersion not recognized. Recommended default is 223.\n");
3302 REAL8 cBetah2 = cBetah * cBetah;
3303 REAL8 cBetah3 = cBetah * cBetah2;
3304 REAL8 cBetah4 = cBetah * cBetah3;
3305 REAL8 cBetah5 = cBetah * cBetah4;
3306 REAL8 cBetah6 = cBetah * cBetah5;
3307 REAL8 cBetah7 = cBetah * cBetah6;
3308 REAL8 cBetah8 = cBetah * cBetah7;
3310 REAL8 sBetah2 = sBetah * sBetah;
3311 REAL8 sBetah3 = sBetah * sBetah2;
3312 REAL8 sBetah4 = sBetah * sBetah3;
3313 REAL8 sBetah5 = sBetah * sBetah4;
3314 REAL8 sBetah6 = sBetah * sBetah5;
3315 REAL8 sBetah7 = sBetah * sBetah6;
3316 REAL8 sBetah8 = sBetah * sBetah7;
3327 if (
l == 2 && mprime == 2){
3329 COMPLEX16 d22[5] = {sBetah4, 2.0*cBetah*sBetah3, pPrec->
sqrt6*sBetah2*cBetah2, 2.0*cBetah3*sBetah, cBetah4};
3331 COMPLEX16 d2m2[5] = {d22[4], -d22[3], d22[2], -d22[1], d22[0]};
3335 hlm += cexp_im_alpha * d2m2[
m+2];
3336 hlmneg += cexp_im_alpha * d22[
m+2];
3340 if (
l == 2 && mprime == 1){
3342 COMPLEX16 d21[5] = {2.0*cBetah*sBetah3, 3.0*sBetah2*cBetah2 - sBetah4, pPrec->
sqrt6*(cBetah3*sBetah - cBetah*sBetah3), cBetah2*(cBetah2 - 3.0*sBetah2), -2.0*cBetah3*sBetah};
3344 COMPLEX16 d2m1[5] = {-d21[4], d21[3], -d21[2], d21[1], -d21[0]};
3348 hlm += cexp_im_alpha * d2m1[
m+2];
3349 hlmneg += cexp_im_alpha * d21[
m+2];
3353 if (
l == 3 && mprime == 3){
3356 COMPLEX16 d33[7] = {sBetah6, pPrec->
sqrt6*cBetah*sBetah5, pPrec->
sqrt15*cBetah2*sBetah4, 2.0*pPrec->
sqrt5*cBetah3*sBetah3, pPrec->
sqrt15*cBetah4*sBetah2, pPrec->
sqrt6*cBetah5*sBetah, cBetah6};
3358 COMPLEX16 d3m3[7] = {d33[6], -d33[5], d33[4], -d33[3], d33[2], -d33[1], d33[0]};
3362 hlm += cexp_im_alpha * d3m3[
m+3];
3363 hlmneg += cexp_im_alpha * d33[
m+3];
3367 if (
l == 3 && mprime == 2){
3370 COMPLEX16 d32[7] = {pPrec->
sqrt6*cBetah*sBetah5, sBetah4*(5.0*cBetah2 - sBetah2), pPrec->
sqrt10*sBetah3*(2.0*cBetah3 - cBetah*sBetah2), pPrec->
sqrt30*cBetah2*(cBetah2 - sBetah2)*sBetah2, pPrec->
sqrt10*cBetah3*(cBetah2*sBetah - 2.0*sBetah3), cBetah4*(cBetah2 - 5.0*sBetah2), -1.0*pPrec->
sqrt6*cBetah5*sBetah};
3372 COMPLEX16 d3m2[7] = {-d32[6], d32[5], -d32[4], d32[3], -d32[2], d32[1], -d32[0]};
3376 hlm += cexp_im_alpha * d3m2[
m+3];
3377 hlmneg += cexp_im_alpha * d32[
m+3];
3381 if (
l == 4 && mprime == 4){
3383 COMPLEX16 d44[9] = {sBetah8, 2.0*pPrec->
sqrt2*cBetah*sBetah7, 2.0*pPrec->
sqrt7*cBetah2*sBetah6, 2.0*pPrec->
sqrt14*cBetah3*sBetah5, pPrec->
sqrt70*cBetah4*sBetah4, 2.0*pPrec->
sqrt14*cBetah5*sBetah3, 2.0*pPrec->
sqrt7*cBetah6*sBetah2, 2.0*pPrec->
sqrt2*cBetah7*sBetah, cBetah8};
3385 COMPLEX16 d4m4[9] = {d44[8], -d44[7], d44[6], -d44[5], d44[4], -d44[3], d44[2], -d44[1], d44[0]};
3389 hlm += cexp_im_alpha * d4m4[
m+4];
3390 hlmneg += cexp_im_alpha * d44[
m+4];
3397 COMPLEX16 exp_imprime_epsilon = cexp(mprime*I*epsilon);
3399 eps_phase_hP_lmprime = 1./exp_imprime_epsilon * (hlmprime + hlmprime_antisym);
3400 eps_phase_hP_lmprime_neg = exp_imprime_epsilon * minus1l * conj(hlmprime - hlmprime_antisym);
3403 (hlminertial)->
data[0] = eps_phase_hP_lmprime * hlm;
3404 (hlminertial)->
data[1] = eps_phase_hP_lmprime_neg * hlmneg;
3437 LALValue *ModeArrayJframe = NULL;
3440 LALDict *lalParams_aux;
3442 if (lalParams == NULL)
3458 if(ModeArrayJframe == NULL)
3487 XLALSimIMRPhenomXPHMOneMode(&hlmpos, &hlmneg, ell, emm, m1_SI, m2_SI, S1x, S1y, S1z, S2x, S2y, S2z, distance, inclination, phiRef, deltaF,
f_min,
f_max, f_ref, lalParams_aux);
3515 for (
INT4 i = -length;
i<=length;
i++)
3517 freqs->
data[
i+length] =
i*deltaF;
3542 INT4 lalParams_In = 0;
3543 if (lalParams == NULL)
3551 if (ModeArray == NULL)
3554 XLAL_PRINT_INFO(
"Using default non-precessing modes for IMRPhenomXPHM: 2|2|, 2|1|, 3|3|, 3|2|, 4|4|.\n");
3570 else {
XLAL_PRINT_INFO(
"Using custom non-precessing modes for PhenomXPHM.\n"); }
3573 if(lalParams_In == 1)
3587 for(
INT4 emm=0; emm<=ell; emm++)
3603 REAL8 *alpha_offset_mprime,
3604 REAL8 *epsilon_offset_mprime,
3660 double omega =
LAL_PI * Mf *2./mprime;
3661 double logomega = log(omega);
3662 double omega_cbrt = cbrt(omega);
3663 double omega_cbrt2 = omega_cbrt * omega_cbrt;
3665 REAL8 alpha_offset_mprime = 0., epsilon_offset_mprime = 0.;
3671 + pPrec->
alpha2 / omega_cbrt2
3672 + pPrec->
alpha3 / omega_cbrt
3674 + pPrec->
alpha5 * omega_cbrt
3675 - alpha_offset_mprime
3684 - epsilon_offset_mprime
3717 size_t iStart = (size_t) (pWF->
fMin / pWF->
deltaF);
3723 REAL8 dfpower = 11./6.;
3729 REAL8 MfMECO, MfLorentzianEnd;
3730 REAL8 dfmerger = 0., dfringdown = 0.;
3731 UINT4 lengthallGrids = 20;
3745 if(ell == 2 && emmprime ==2){
3746 MfMECO = pWF->
fMECO;
3748 printf(
"\nfRING = %e\n",pWF->
fRING);
3749 printf(
"fDAMP = %e\n",pWF->
fDAMP);
3750 printf(
"alphaL22 = %.16e", pPhase22->
cLovfda/pWF->
eta);
3780 MfLorentzianEnd = pWFHM->
fRING + 2*pWFHM->
fDAMP;
3782 printf(
"\nfRING = %e\n",pWFHM->
fRING);
3783 printf(
"fDAMP = %e\n",pWFHM->
fDAMP);
3784 printf(
"alphaL = %.16e", pPhase->
alphaL);
3795 if (allGrids == NULL)
3798 printf(
"Malloc of allGrids failed!\n");
3799 printf(
"nGridsUsed = %i\n", nGridsUsed);
3806 UINT4 actualnumberofGrids = 0;
3808 UINT4 lenCoarseArray = 0;
3812 for(
UINT4 kk = 0; kk < nGridsUsed; kk++){
3813 lenCoarseArray = lenCoarseArray + allGrids[kk].
Length;
3814 actualnumberofGrids++;
3817 printf(
"\nkk = %i\n",kk);
3818 printf(
"xStart: %.16e\n", allGrids[kk].xStart);
3819 printf(
"xEnd: %.16e\n", allGrids[kk].xEndRequested);
3820 printf(
"Length: %i\n", allGrids[kk].Length);
3821 printf(
"deltax: %.16e\n", allGrids[kk].deltax);
3822 printf(
"evaldMf: %.16e\n", evaldMf);
3823 printf(
"xMax: %.16e\n", allGrids[kk].xMax);
3824 printf(
"Last grid.xMax = %.16f\n", allGrids[actualnumberofGrids-1].xMax);
3827 if(allGrids[kk].xMax + evaldMf >= Mfmax){
3833 while(allGrids[actualnumberofGrids-1].xMax < Mfmax){
3834 allGrids[actualnumberofGrids-1].
xMax = allGrids[actualnumberofGrids-1].
xMax + allGrids[actualnumberofGrids-1].
deltax;
3835 allGrids[actualnumberofGrids-1].
Length = allGrids[actualnumberofGrids-1].
Length + 1;
3840 printf(
"\nactualnumberofGrids = %i\n", actualnumberofGrids);
3841 printf(
"lenCoarseArray = %i\n", lenCoarseArray);
3842 printf(
"Last grid.xMax = %.16f", allGrids[actualnumberofGrids-1].xMax);
3850 UINT4 lencoarseFreqs = 0;
3852 for(
UINT4 kk = 0; kk < actualnumberofGrids; kk++){
3853 for(
INT4 ll = 0; ll < allGrids[kk].
Length; ll++){
3854 (*coarseFreqs)->data[lencoarseFreqs] = (allGrids[kk].
xStart + allGrids[kk].
deltax*ll);
3862 printf(
"\n******** Coarse frequencies array done ********* \n");
3863 printf(
"\nlencoarseFreqs, coarse[0], coarse[-1], Mfmax = %i %.16e %.16e %.16e\n",lencoarseFreqs,
XLALSimIMRPhenomXUtilsMftoHz((*coarseFreqs)->data[0],pWF->
Mtot),
XLALSimIMRPhenomXUtilsMftoHz((*coarseFreqs)->data[lencoarseFreqs-1], pWF->
Mtot),
XLALSimIMRPhenomXUtilsMftoHz(Mfmax,pWF->
Mtot));
3868 return actualnumberofGrids;
void XLALDestroyDict(LALDict *dict)
LALDict * XLALDictDuplicate(const LALDict *orig)
LALDict * XLALCreateDict(void)
int XLALSimIMRPhenomHMGethlmModes(SphHarmFrequencySeries **hlms, REAL8Sequence *freqs, REAL8 m1_SI, REAL8 m2_SI, REAL8 chi1x, REAL8 chi1y, REAL8 chi1z, REAL8 chi2x, REAL8 chi2y, REAL8 chi2z, const REAL8 phiRef, const REAL8 deltaF, REAL8 f_ref, LALDict *extraParams)
static size_t NextPow2(const size_t n)
IMRPhenomX_UsefulPowers powers_of_lalpi
int IMRPhenomXASGenerateFD(COMPLEX16FrequencySeries **htilde22, const REAL8Sequence *freqs_In, IMRPhenomXWaveformStruct *pWF, LALDict *lalParams)
INT4 IMRPhenomXHM_PNR_SetPhaseAlignmentParams(INT4 ell, INT4 emm, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, LALDict *lalParams)
REAL8 IMRPhenomX_PNR_LinearFrequencyMap(REAL8 Mf, REAL8 ell, REAL8 emm, REAL8 Mf_lower, REAL8 Mf_upper, REAL8 Mf_RD_22, REAL8 Mf_RD_lm, UINT4 INSPIRAL)
Computes a linear frequency map for the HM PNR angles based on the linear frequency mapping used orig...
INT4 IMRPhenomX_PNR_RemapThetaJSF(REAL8 beta_ref, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, LALDict *lalParams)
This code recomputes the skymapped locations in the J-frame using the new value of beta computed from...
INT4 IMRPhenomX_PNR_LinearFrequencyMapTransitionFrequencies(REAL8 *Mf_low, REAL8 *Mf_high, REAL8 emmprime, REAL8 Mf_RD_22, REAL8 Mf_RD_lm, IMRPhenomXPrecessionStruct *pPrec)
Compute the transition frequencies for the HM PNR angle mapping.
int IMRPhenomXSetWaveformVariables(IMRPhenomXWaveformStruct *wf, const REAL8 m1_SI, const REAL8 m2_SI, const REAL8 chi1L_In, const REAL8 chi2L_In, const REAL8 deltaF, const REAL8 fRef, const REAL8 phi0, const REAL8 f_min, const REAL8 f_max, const REAL8 distance, const REAL8 inclination, LALDict *LALParams, UNUSED const UINT4 debug)
int IMRPhenomXGetAmplitudeCoefficients(IMRPhenomXWaveformStruct *pWF, IMRPhenomXAmpCoefficients *pAmp)
int IMRPhenomX_Initialize_Powers(IMRPhenomX_UsefulPowers *p, REAL8 number)
int IMRPhenomXGetPhaseCoefficients(IMRPhenomXWaveformStruct *pWF, IMRPhenomXPhaseCoefficients *pPhase)
INT4 check_input_mode_array(LALDict *lalParams)
int IMRPhenomXWignerdCoefficients(REAL8 *cos_beta_half, REAL8 *sin_beta_half, const REAL8 v, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec)
int gamma_from_alpha_cosbeta(double *gamma, double Mf, double deltaMf, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec)
vector IMRPhenomX_Return_phi_zeta_costhetaL_MSA(const double v, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec)
Wrapper to generate , and at a given frequency.
double alphaMRD(double Mf, PhenomXPalphaMRD *alpha_params)
int IMRPhenomX_Initialize_Euler_Angles(IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, LALDict *lalParams)
Wrapper of IMRPhenomX_SpinTaylorAnglesSplinesAll: fmin and fmax are determined by the function based ...
int IMRPhenomXWignerdCoefficients_cosbeta(REAL8 *cos_beta_half, REAL8 *sin_beta_half, const REAL8 cos_beta)
int IMRPhenomXGetAndSetPrecessionVariables(IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, REAL8 m1_SI, REAL8 m2_SI, REAL8 chi1x, REAL8 chi1y, REAL8 chi1z, REAL8 chi2x, REAL8 chi2y, REAL8 chi2z, LALDict *lalParams, INT4 debug_flag)
Function to populate the IMRPhenomXPrecessionStruct:
double betaMRD(double Mf, UNUSED IMRPhenomXWaveformStruct *pWF, PhenomXPbetaMRD *beta_params)
int SetupWFArrays(REAL8Sequence **freqs, COMPLEX16FrequencySeries **htildelm, const REAL8Sequence *freqs_In, IMRPhenomXWaveformStruct *pWF, LIGOTimeGPS ligotimegps_zero)
int IMRPhenomXHMGenerateFDOneMode(COMPLEX16FrequencySeries **htildelm, const REAL8Sequence *freqs_In, IMRPhenomXWaveformStruct *pWF, UINT4 ell, UINT4 emm, LALDict *lalParams)
IMRPhenomX_UsefulPowers powers_of_lalpiHM
void IMRPhenomXHM_SetHMWaveformVariables(int ell, int emm, IMRPhenomXHMWaveformStruct *wf, IMRPhenomXWaveformStruct *wf22, QNMFits *qnms, LALDict *LALParams)
void IMRPhenomXHM_GetAmplitudeCoefficients(IMRPhenomXHMAmpCoefficients *pAmp, IMRPhenomXHMPhaseCoefficients *pPhase, IMRPhenomXAmpCoefficients *pAmp22, IMRPhenomXPhaseCoefficients *pPhase22, IMRPhenomXHMWaveformStruct *pWFHM, IMRPhenomXWaveformStruct *pWF22)
void IMRPhenomXHM_GetPhaseCoefficients(IMRPhenomXHMAmpCoefficients *pAmp, IMRPhenomXHMPhaseCoefficients *pPhase, IMRPhenomXAmpCoefficients *pAmp22, IMRPhenomXPhaseCoefficients *pPhase22, IMRPhenomXHMWaveformStruct *pWFHM, IMRPhenomXWaveformStruct *pWF22, UNUSED LALDict *lalParams)
void GetSpheroidalCoefficients(IMRPhenomXHMPhaseCoefficients *pPhase, IMRPhenomXPhaseCoefficients *pPhase22, IMRPhenomXHMWaveformStruct *pWFHM, IMRPhenomXWaveformStruct *pWF22)
void IMRPhenomXHM_FillAmpFitsArray(IMRPhenomXHMAmpCoefficients *pAmp)
void IMRPhenomXHM_FillPhaseFitsArray(IMRPhenomXHMPhaseCoefficients *pPhase)
REAL8 IMRPhenomXHM_GenerateRingdownFrequency(UINT4 ell, UINT4 emm, IMRPhenomXWaveformStruct *wf22)
void IMRPhenomXHM_Initialize_QNMs(QNMFits *qnms)
static double deltaF_ringdownBin(REAL8 fdamp, REAL8 alpha4, REAL8 LAMBDA, REAL8 abserror)
INT4 XLALSimIMRPhenomXMultibandingGrid(REAL8 fstartIn, REAL8 fend, REAL8 MfLorentzianEnd, REAL8 Mfmax, REAL8 evaldMf, REAL8 dfpower, REAL8 dfcoefficient, IMRPhenomXMultiBandingGridStruct *allGrids, REAL8 dfmerger, REAL8 dfringdown)
INT4 deltaF_MergerRingdown(REAL8 *dfmerger, REAL8 *dfringdown, REAL8 resTest, IMRPhenomXHMWaveformStruct *pWFHM, IMRPhenomXHMAmpCoefficients *pAmp, IMRPhenomXHMPhaseCoefficients *pPhase)
static double deltaF_mergerBin(REAL8 fdamp, REAL8 alpha4, REAL8 abserror)
int IMRPhenomXHMMultiBandOneModeMixing(COMPLEX16FrequencySeries **htildelm, COMPLEX16FrequencySeries *htilde22, IMRPhenomXWaveformStruct *pWF, UINT4 ell, UINT4 emm, LALDict *lalParams)
int IMRPhenomXHMMultiBandOneMode(COMPLEX16FrequencySeries **htildelm, IMRPhenomXWaveformStruct *pWF, UINT4 ell, UINT4 emm, LALDict *lalParams)
static int IMRPhenomXPHM_hplushcross_from_modes(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, const REAL8Sequence *freqs_In, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, LALDict *lalParams)
LALDict * IMRPhenomXPHM_setup_mode_array(LALDict *lalParams)
Wrapper function for setup ModeArray of modes in the precessing frame to be twisted up.
int XLALSimIMRPhenomXPHMModes(SphHarmFrequencySeries **hlms, REAL8 m1_SI, REAL8 m2_SI, 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 *lalParams)
Function to obtain a SphHarmFrequencySeries with the individual modes h_lm.
static int IMRPhenomXPHM_OneMode(COMPLEX16FrequencySeries **hlmpos, COMPLEX16FrequencySeries **hlmneg, const REAL8Sequence *freqs_In, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, UINT4 ell, INT4 m, LALDict *lalParams)
Core funciton to compute an individual precessing mode hlm in the inertial J-frame.
INT4 XLALSimIMRPhenomXPHMMultibandingGrid(REAL8Sequence **coarseFreqs, UINT4 ell, UINT4 emmprime, IMRPhenomXWaveformStruct *pWF, LALDict *lalParams)
static int IMRPhenomXPHMTwistUpOneMode(const REAL8 Mf, const COMPLEX16 hlmprime, const COMPLEX16 hlmprime_antisym, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, UINT4 l, UINT4 mprime, INT4 m, COMPLEX16Sequence *hlminertial)
INT4 check_input_mode_array_Jframe(LALValue *ModeArrayJframe)
static double Get_alpha_epsilon_offset(REAL8 *alpha_offset_mprime, REAL8 *epsilon_offset_mprime, INT4 mprime, IMRPhenomXPrecessionStruct *pPrec)
static int IMRPhenomXPHMTwistUp(const REAL8 Mf, const COMPLEX16 hHM, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, INT4 ell, INT4 emmprime, COMPLEX16 *hp, COMPLEX16 *hc)
static int IMRPhenomXPHM_hplushcross(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, const REAL8Sequence *freqs_In, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, LALDict *lalParams)
Core function of XLALSimIMRPhenomXPHM and XLALSimIMRPhenomXPHMFrequencySequence.
static int Get_alpha_beta_epsilon(REAL8 *alpha, REAL8 *cBetah, REAL8 *sBetah, REAL8 *epsilon, INT4 mprime, REAL8 Mf, IMRPhenomXPrecessionStruct *pPrec, IMRPhenomXWaveformStruct *pWF)
INT4 XLALIMRPhenomXPCheckMassesAndSpins(REAL8 *m1, REAL8 *m2, REAL8 *chi1x, REAL8 *chi1y, REAL8 *chi1z, REAL8 *chi2x, REAL8 *chi2y, REAL8 *chi2z)
Check if m1 > m2.
REAL8 XLALSimIMRPhenomXUtilsHztoMf(REAL8 fHz, REAL8 Mtot_Msun)
Convert from frequency in Hz to geometric frequency.
REAL8 XLALSimIMRPhenomXUtilsMftoHz(REAL8 Mf, REAL8 Mtot_Msun)
Convert from geometric frequency to Hz.
static double beta(const double a, const double b, const sysq *system)
Internal function that computes the spin-orbit couplings.
void XLALDestroyValue(LALValue *value)
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
COMPLEX16FrequencySeries * XLALResizeCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series, int first, size_t length)
void XLALDestroyCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series)
void * XLALMalloc(size_t n)
int XLALSimIMRPhenomXPHMFromModes(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, REAL8 m1_SI, REAL8 m2_SI, REAL8 chi1x, REAL8 chi1y, REAL8 chi1z, REAL8 chi2x, REAL8 chi2y, REAL8 chi2z, REAL8 distance, REAL8 inclination, REAL8 phiRef, REAL8 f_min, REAL8 f_max, REAL8 deltaF, REAL8 fRef_In, LALDict *lalParams)
Returns hptilde and hctilde of the multimode precessing waveform for positive frequencies in an equal...
int XLALSimIMRPhenomXPHMFrequencySequence(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, const REAL8Sequence *freqs, REAL8 m1_SI, REAL8 m2_SI, REAL8 chi1x, REAL8 chi1y, REAL8 chi1z, REAL8 chi2x, REAL8 chi2y, REAL8 chi2z, REAL8 distance, REAL8 inclination, REAL8 phiRef, REAL8 fRef_In, LALDict *lalParams)
Returns hptilde and hctilde as a complex frequency series with entries exactly at the frequencies spe...
int XLALSimIMRPhenomXPHMFrequencySequenceOneMode(COMPLEX16FrequencySeries **hlmpos, COMPLEX16FrequencySeries **hlmneg, const REAL8Sequence *freqs, const UINT4 l, const INT4 m, REAL8 m1_SI, REAL8 m2_SI, REAL8 chi1x, REAL8 chi1y, REAL8 chi1z, REAL8 chi2x, REAL8 chi2y, REAL8 chi2z, const REAL8 distance, const REAL8 inclination, const REAL8 phiRef, const REAL8 fRef_In, LALDict *lalParams)
Function to compute one hlm precessing mode on a custom frequency grid.
int XLALSimIMRPhenomXPHM(COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, REAL8 m1_SI, REAL8 m2_SI, REAL8 chi1x, REAL8 chi1y, REAL8 chi1z, REAL8 chi2x, REAL8 chi2y, REAL8 chi2z, REAL8 distance, REAL8 inclination, REAL8 phiRef, REAL8 f_min, REAL8 f_max, REAL8 deltaF, REAL8 fRef_In, LALDict *lalParams)
Returns hptilde and hctilde of the multimode precessing waveform for positive frequencies in an equal...
int IMRPhenomX_PNR_GenerateAntisymmetricWaveform(REAL8Sequence *antisymamp, REAL8Sequence *antisymphase, const REAL8Sequence *freqs, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, LALDict *lalParams)
int XLALSimIMRPhenomXPHMOneMode(COMPLEX16FrequencySeries **hlmpos, COMPLEX16FrequencySeries **hlmneg, const UINT4 l, const INT4 m, REAL8 m1_SI, REAL8 m2_SI, REAL8 chi1x, REAL8 chi1y, REAL8 chi1z, REAL8 chi2x, REAL8 chi2y, REAL8 chi2z, const REAL8 distance, const REAL8 inclination, const REAL8 phiRef, const REAL8 deltaF, const REAL8 f_min, const REAL8 f_max, const REAL8 fRef_In, LALDict *lalParams)
Function to compute one hlm precessing mode in an uniform frequency grid.
int IMRPhenomX_PNR_GeneratePNRAngleInterpolants(IMRPhenomX_PNR_angle_spline *angle_spline, IMRPhenomXWaveformStruct *pWF, IMRPhenomXPrecessionStruct *pPrec, LALDict *lalparams)
Generate the tuned precession angles outlined in arXiv:2107.08876 specifically populate the angle int...
#define LAL_SIM_L_MAX_MODE_ARRAY
Maximum L spherical harmonic mode that is supported in Mode Array.
COMPLEX16FrequencySeries * XLALSphHarmFrequencySeriesGetMode(SphHarmFrequencySeries *ts, UINT4 l, INT4 m)
Get the time series of a waveform's (l,m) spherical harmonic mode from a SphHarmFrequencySeries linke...
SphHarmFrequencySeries * XLALSphHarmFrequencySeriesAddMode(SphHarmFrequencySeries *appended, const COMPLEX16FrequencySeries *inmode, UINT4 l, INT4 m)
Prepend a node to a linked list of SphHarmFrequencySeries, or create a new head.
void XLALDestroySphHarmFrequencySeries(SphHarmFrequencySeries *ts)
Delete list from current pointer to the end of the list.
void XLALSphHarmFrequencySeriesSetFData(SphHarmFrequencySeries *ts, REAL8Sequence *fdata)
Set the tdata member for all nodes in the list.
COMPLEX16Sequence * XLALCreateCOMPLEX16Sequence(size_t length)
void XLALDestroyREAL8Sequence(REAL8Sequence *sequence)
void XLALDestroyCOMPLEX16Sequence(COMPLEX16Sequence *sequence)
REAL8Sequence * XLALCreateREAL8Sequence(size_t length)
COMPLEX16 XLALSpinWeightedSphericalHarmonic(REAL8 theta, REAL8 phi, int s, int l, int m)
const LALUnit lalStrainUnit
const LALUnit lalSecondUnit
LALUnit * XLALUnitMultiply(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
#define XLAL_PRINT_INFO(...)
#define XLAL_CHECK(assertion,...)
#define XLAL_PRINT_WARNING(...)
#define XLAL_PRINT_ERROR(...)
gsl_spline * beta_spline
beta cubic spline
gsl_interp_accel * beta_acc
beta cubic spline accelerator
gsl_interp_accel * alpha_acc
alpha cubic spline accelerator
gsl_interp_accel * gamma_acc
gamma cubic spline accelerator
gsl_spline * gamma_spline
gamma cubic spline
gsl_spline * alpha_spline
alpha cubic spline
REAL8 epsilon_offset_3
offset passed to modes.
gsl_interp_accel * gamma_acc
PhenomXPbetaMRD * beta_params
Parameters needed for analytical MRD continuation of cosbeta.
REAL8 alpha_offset_4
offset passed to modes.
gsl_spline * gamma_spline
REAL8 epsilon3
Coefficient of .
REAL8 zeta_polarization
Angle to rotate the polarizations.
REAL8 cosbeta_ftrans
Record value of cosbeta at end of inspiral, used in IMRPhenomXPHMTwistUp and IMRPhenomXPHMTwistUpOneM...
REAL8 alpha_ftrans
Record value of alpha at end of inspiral, used in IMRPhenomXPHMTwistUp and IMRPhenomXPHMTwistUpOneMod...
INT4 MBandPrecVersion
Flag to control multibanding for Euler angles.
REAL8 thetaJN
Angle between J0 and line of sight (z-direction)
REAL8 alpha_offset_3
offset passed to modes.
REAL8 epsilon5
Coefficient of .
REAL8 epsilon_offset_4
offset passed to modes.
REAL8 epsilon1
Coefficient of .
REAL8 alpha_offset_1
offset passed to modes.
INT4 IMRPhenomXPNRUseTunedAngles
REAL8 gamma_ref
Record value of gamma at f_ref.
IMRPhenomXWaveformStruct * pWF22AS
REAL8 gamma_ftrans
Record value of gamma at end of inspiral, used in IMRPhenomXPHMTwistUp and IMRPhenomXPHMTwistUpOneMod...
REAL8 alpha3
Coefficient of .
REAL8 epsilon_offset
Offset for .
gsl_interp_accel * alpha_acc
INT4 IMRPhenomXPrecVersion
Flag to set version of Euler angles used.
REAL8 epsilon4L
Coefficient of .
REAL8 gamma_in
Record last value of gamma, used in IMRPhenomXPHMTwistUp and IMRPhenomXPHMTwistUpOneMode.
UINT4 PNRInspiralScaling
Enforce inpsiral scaling for HM angles outside of calibration window.
REAL8 alpha_offset
Offset for .
REAL8 epsilon0
Coefficient of .
REAL8 epsilon2
Coefficient of .
REAL8 alpha0
Coefficient of .
REAL8 alpha1
Coefficient of .
INT4 IMRPhenomXAntisymmetricWaveform
PhenomXPalphaMRD * alpha_params
Parameters needed for analytical MRD continuation of alpha.
gsl_spline * alpha_spline
REAL8 PolarizationSymmetry
REAL8 epsilon_offset_1
offset passed to modes.
REAL8 alpha4L
Coefficient of .
gsl_interp_accel * cosbeta_acc
gsl_spline * cosbeta_spline
REAL8 alpha_ref
Record value of alpha at f_ref.
REAL8 alpha5
Coefficient of .
REAL8 alpha2
Coefficient of .