20 #include <lal/LALSimIMR.h>
21 #include <lal/SphericalHarmonics.h>
22 #include <lal/Sequence.h>
24 #include <lal/Units.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>
41 #ifndef PHENOMXHMDEBUG
43 #define PHENOMXDEBUG 0
46 #define PHENOMXDEBUG 1
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)
863 "Error: IMRPhenomX_PNR_RemapThetaJSF failed in IMRPhenomX_PNR_GeneratePNRAngles.");
872 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
883 for (
UINT4 emmprime = 1; emmprime <= ell; emmprime++)
897 if((pWF->
q == 1) && (pWF->
chi1L == pWF->
chi2L) && (emmprime % 2 != 0))
915 printf(
"\n\n*********************************\n*Non-precessing Mode %i%i \n******************************\n",ell, emmprime);
922 sprintf(fileSpec,
"angles_hphc_%i%i.dat", ell, emmprime);
926 sprintf(fileSpec,
"angles_hphc_MB_%i%i.dat", ell, emmprime);
928 printf(
"\nOutput angle file: %s\r\n", fileSpec);
929 fileangle = fopen(fileSpec,
"w");
931 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);
932 fprintf(fileangle,
"#fHz cexp_i_alpha(re im) cexp_i_epsilon(re im) cexp_i_betah(re im)\n");
943 if(ell % 2 !=0) minus1l = -1;
948 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);
962 if (thresholdMB == 0){
963 if(ell == 2 && emmprime == 2)
975 if(ell==3 && emmprime==2){
998 if(ell==2 && emmprime==2)
1000 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
1022 && ((*hctilde)->data->length==htildelm->
data->
length),
1024 "Inconsistent lengths between frequency series htildelm (%d), hptilde (%d) and hctilde (%d).",
1025 htildelm->
data->
length, (*hptilde)->data->length, (*hctilde)->data->length
1042 printf(
"\n****************************************************************\n");
1043 printf(
"\n* NOT USING MBAND FOR ANGLES %i *\n", offset);
1044 printf(
"\n****************************************************************\n");
1051 printf(
"\n** We will not twist up the HM waveforms **\n");
1056 REAL8 Mf_high = 0.0;
1061 if (IMRPhenomXPNRUseTunedAngles)
1064 if((ell==2)&&(emmprime==2))
1085 double Mf = pWF->
M_sec * freqs->
data[idx];
1090 hlmcoprec = htildelm->
data->
data[idx + offset];
1097 hplus = 0.5 * hlmcoprec;
1098 hcross = -0.5 * I * hlmcoprec;
1110 if(IMRPhenomXPNRUseTunedAngles)
1124 if(ell == 2 && emmprime == 2 && AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
1128 hlmcoprec_antiSym = antiSym_amp->
data[idx]*cexp(I*antiSym_phi->
data[idx]);
1130 IMRPhenomXPHMTwistUp(Mf, hlmcoprec_antiSym, pWF, pPrec, ell, emmprime, &hplus_antiSym, &hcross_antiSym);
1132 hplus += hplus_antiSym;
1133 hcross += hcross_antiSym;
1137 (*hptilde)->data->data[idx + offset] += hplus;
1138 (*hctilde)->data->data[idx + offset] += hcross;
1143 (*hptilde)->data->data[idx + offset] += 0.0 + I*0.0;
1144 (*hctilde)->data->data[idx + offset] += 0.0 + I*0.0;
1148 if(IMRPhenomXPNRUseTunedAngles)
1150 gsl_interp_accel_reset(hm_angle_spline->
alpha_acc);
1151 gsl_interp_accel_reset(hm_angle_spline->
beta_acc);
1152 gsl_interp_accel_reset(hm_angle_spline->
gamma_acc);
1175 printf(
"\n****************************************************************\n");
1176 printf(
"\n* USING MBAND FOR ANGLES *\n");
1177 printf(
"\n****************************************************************\n");
1191 REAL8 epsilon = 0.0;
1201 if(IMRPhenomXPNRUseTunedAngles)
1203 REAL8 Mf_high = 0.0;
1207 if ((ell==2)&&(emmprime==2))
1225 FILE *fileangle0101;
1226 char fileSpec0101[40];
1228 sprintf(fileSpec0101,
"angles_pnr_MB_%i%i.dat", ell, emmprime);
1230 fileangle0101 = fopen(fileSpec0101,
"w");
1232 fprintf(fileangle0101,
"#Mf fHz alpha beta gamma\n");
1234 fprintf(fileangle0101,
"#Mf_low = %.16e\n",Mf_low);
1235 fprintf(fileangle0101,
"#Mf_high = %.16e\n",Mf_high);
1236 fprintf(fileangle0101,
"#Mf_RD_22 = %.16e\n",Mf_RD_22);
1237 fprintf(fileangle0101,
"#Mf_RD_lm = %.16e\n",Mf_RD_lm);
1241 for(
UINT4 j=0; j<lenCoarseArray; j++)
1248 f_mapped = (f_mapped > fCut) ? fCut : f_mapped;
1254 vbetah[j] =
beta / 2.0;
1258 fprintf(fileangle0101,
"%.16e\t%.16e\t%.16e\t%.16e\t%.16e\n",Mf,f_mapped,valpha[j],
beta,vepsilon[j]);
1265 fclose(fileangle0101);
1268 gsl_interp_accel_reset(hm_angle_spline->
alpha_acc);
1269 gsl_interp_accel_reset(hm_angle_spline->
beta_acc);
1270 gsl_interp_accel_reset(hm_angle_spline->
gamma_acc);
1284 for(
UINT4 j=0; j<lenCoarseArray; j++)
1292 vepsilon[j] = epsilon;
1293 vbetah[j] = acos(cBetah);
1305 for(
UINT4 j=0; j<lenCoarseArray; j++)
1309 const REAL8 v = cbrt (
LAL_PI * Mf * (2.0 / emmprime) );
1311 REAL8 cos_beta = 0.0;
1314 REAL8 alpha_offset_mprime = 0, epsilon_offset_mprime = 0;
1317 valpha[j] = vangles.
x - alpha_offset_mprime;
1318 vepsilon[j] = vangles.
y - epsilon_offset_mprime;
1319 cos_beta = vangles.
z;
1324 vbetah[j] = acos(cBetah);
1346 for(
UINT4 j=0; j<lenCoarseArray; j++)
1350 Mf = coarseFreqs->
data[j]*(2.0/emmprime);
1353 if(Mf< pPrec->ftrans_MRD)
1371 REAL8 dMf=(coarseFreqs->
data[j]-coarseFreqs->
data[j-1])* (2.0 / emmprime);
1372 REAL8 deltagamma=0.;
1401 if(fabs(cos_beta)>1)
1402 cos_beta=copysign(1.0, cos_beta);
1404 valpha[j]= alpha_i- alpha_offset_mprime;
1405 vepsilon[j] = -
gamma - epsilon_offset_mprime;
1410 vbetah[j] = acos(cBetah);
1422 XLAL_ERROR(
XLAL_EINVAL,
"Error: IMRPhenomXPrecVersion not recognized. Recommended default is 223.\n");
1433 UINT4 fine_count = 0, ratio;
1434 REAL8 Omega_alpha, Omega_epsilon, Omega_betah, Qalpha, Qepsilon, Qbetah;
1435 REAL8 Mfhere, Mfnext, evaldMf;
1436 Mfnext = coarseFreqs->
data[0];
1445 UINT4 length_fine_grid = iStop + 3;
1453 printf(
"\n\nLENGTHS fine grid estimate, coarseFreqs->length = %i %i\n", length_fine_grid, lenCoarseArray);
1454 printf(
"fine_count, htildelm->length, offset = %i %i %i\n", fine_count, htildelm->
data->
length, offset);
1458 for(
UINT4 j = 0; j<lenCoarseArray-1 && fine_count < iStop; j++)
1461 Mfnext = coarseFreqs->
data[j+1];
1463 Omega_alpha = (valpha[j + 1] - valpha[j]) /(Mfnext - Mfhere);
1464 Omega_epsilon = (vepsilon[j + 1] - vepsilon[j])/(Mfnext - Mfhere);
1465 Omega_betah = (vbetah[j + 1] - vbetah[j]) /(Mfnext - Mfhere);
1467 cexp_i_alpha[fine_count] = cexp(I*valpha[j]);
1468 cexp_i_epsilon[fine_count] = cexp(I*vepsilon[j]);
1469 cexp_i_betah[fine_count] = cexp(I*vbetah[j]);
1471 Qalpha = cexp(I*evaldMf*Omega_alpha);
1472 Qepsilon = cexp(I*evaldMf*Omega_epsilon);
1473 Qbetah = cexp(I*evaldMf*Omega_betah);
1477 REAL8 dratio = (Mfnext-Mfhere)/evaldMf;
1478 UINT4 ceil_ratio = ceil(dratio);
1479 UINT4 floor_ratio = floor(dratio);
1482 if(fabs(dratio-ceil_ratio) < fabs(dratio-floor_ratio))
1488 ratio = floor_ratio;
1493 for(
UINT4 kk = 1; kk < ratio && fine_count < iStop; kk++){
1494 cexp_i_alpha[fine_count] = Qalpha*cexp_i_alpha[fine_count-1];
1495 cexp_i_epsilon[fine_count] = Qepsilon*cexp_i_epsilon[fine_count-1];
1496 cexp_i_betah[fine_count] = Qbetah*cexp_i_betah[fine_count-1];
1507 printf(
"fine_count, htildelm->length, offset = %i %i %i\n", fine_count, htildelm->
data->
length, offset);
1512 for (
UINT4 idx = 0; idx < fine_count; idx++)
1514 double Mf = pWF->
M_sec * (idx + offset)*pWF->
deltaF;
1516 hlmcoprec = htildelm->
data->
data[idx + offset];
1530 if(ell == 2 && emmprime == 2 && AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
1534 hlmcoprec_antiSym = antiSym_amp->
data[idx] * cexp(I*antiSym_phi->
data[idx]);
1536 IMRPhenomXPHMTwistUp(Mf, hlmcoprec_antiSym, pWF, pPrec, ell, emmprime, &hplus_antiSym, &hcross_antiSym);
1538 hplus += hplus_antiSym;
1539 hcross += hcross_antiSym;
1542 (*hptilde)->data->data[idx + offset] += hplus ;
1543 (*hctilde)->data->data[idx + offset] += hcross ;
1560 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
1566 if (IMRPhenomXPNRUseTunedAngles){
1571 gsl_interp_accel_free(hm_angle_spline->
alpha_acc);
1572 gsl_interp_accel_free(hm_angle_spline->
beta_acc);
1573 gsl_interp_accel_free(hm_angle_spline->
gamma_acc);
1594 REAL8 cosPolFac, sinPolFac;
1599 for (
UINT4 i = offset;
i < (*hptilde)->data->length;
i++)
1601 PhPpolp = (*hptilde)->data->data[
i];
1602 PhPpolc = (*hctilde)->data->data[
i];
1604 (*hptilde)->data->data[
i] = cosPolFac * PhPpolp + sinPolFac * PhPpolc;
1605 (*hctilde)->data->data[
i] = cosPolFac * PhPpolc - sinPolFac * PhPpolp;
1624 gsl_interp_accel_free(pPrec->
alpha_acc);
1625 gsl_interp_accel_free(pPrec->
gamma_acc);
1632 printf(
"\n******Leaving IMRPhenomXPHM_hplushcross*****\n");
1670 if (ModeArray == NULL)
1683 size_t npts = (*hptilde)->data->length;
1685 XLAL_CHECK (*hctilde,
XLAL_ENOMEM,
"Failed to allocated waveform COMPLEX16FrequencySeries of length %zu.", npts);
1686 memset((*hctilde)->data->data, 0, npts *
sizeof(
COMPLEX16));
1699 for(
UINT4 ell = 2; ell <= 4; ell++)
1701 for(
INT4 emm = -1*ell; emm <= (
INT4)ell; emm++)
1704 printf(
"\n*****************************************************************\n");
1705 printf(
" Precessing mode (%i%i) ", ell, emm);
1706 printf(
"*******************************************************************\n");
1724 "Inconsistent lengths between frequency series hlmpos (%d), hlmneg (%d), hptilde (%d) and hctilde (%d).",
1739 (*hptilde)->data->data[
i] += 0.5*(hlmpos->
data->
data[
i] * Ylm + conj(hlmneg->
data->
data[
i]) * Ylmstar);
1740 (*hctilde)->data->data[
i] += I*0.5*(hlmpos->
data->
data[
i] * Ylm - conj(hlmneg->
data->
data[
i]) * Ylmstar);
1756 REAL8 cosPolFac, sinPolFac;
1761 for (
UINT4 i = offset;
i < (*hptilde)->data->length;
i++)
1763 PhPpolp = (*hptilde)->data->data[
i];
1764 PhPpolc = (*hctilde)->data->data[
i];
1766 (*hptilde)->data->data[
i] = cosPolFac * PhPpolp + sinPolFac * PhPpolc;
1767 (*hctilde)->data->data[
i] = cosPolFac * PhPpolc - sinPolFac * PhPpolp;
1784 gsl_interp_accel_free(pPrec->
alpha_acc);
1785 gsl_interp_accel_free(pPrec->
gamma_acc);
1792 printf(
"\n******Leaving IMRPhenomXPHM_hplushcross_from_modes*****\n");
1822 double epsilon = 0.0;
1824 double cBetah = 0.0;
1825 double sBetah = 0.0;
1827 COMPLEX16 cexp_i_alpha, cexp_i_epsilon = 1;
1860 const double v = cbrt (
LAL_PI * Mf * (2.0 / mprime) );
1862 double cos_beta = 0.0;
1865 REAL8 alpha_offset_mprime = 0, epsilon_offset_mprime = 0;
1868 alpha = vangles.
x - alpha_offset_mprime;
1869 epsilon = vangles.
y - epsilon_offset_mprime;
1870 cos_beta = vangles.
z;
1887 REAL8 Mfprime = Mf * (2.0 / mprime);
1891 if(Mfprime< pPrec->ftrans_MRD)
1897 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);
1916 REAL8 deltagamma=0.;
1940 alpha = alpha_i - alpha_offset_mprime;
1941 epsilon = -
gamma - epsilon_offset_mprime;
1953 XLAL_ERROR(
XLAL_EINVAL,
"Error. IMRPhenomXPrecVersion not recognized. Recommended default is 223.\n");
1958 cexp_i_alpha = cexp(+I*
alpha);
1962 cexp_i_epsilon = cexp(+I*epsilon);
1975 REAL8 cBetah2 = cBetah * cBetah;
1976 REAL8 cBetah3 = cBetah * cBetah2;
1977 REAL8 cBetah4 = cBetah * cBetah3;
1978 REAL8 cBetah5 = cBetah * cBetah4;
1979 REAL8 cBetah6 = cBetah * cBetah5;
1980 REAL8 cBetah7 = cBetah * cBetah6;
1981 REAL8 cBetah8 = cBetah * cBetah7;
1983 REAL8 sBetah2 = sBetah * sBetah;
1984 REAL8 sBetah3 = sBetah * sBetah2;
1985 REAL8 sBetah4 = sBetah * sBetah3;
1986 REAL8 sBetah5 = sBetah * sBetah4;
1987 REAL8 sBetah6 = sBetah * sBetah5;
1988 REAL8 sBetah7 = sBetah * sBetah6;
1989 REAL8 sBetah8 = sBetah * sBetah7;
2000 if (
l == 2 && mprime == 2){
2003 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2005 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2006 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2008 COMPLEX16 cexp_im_alpha_l2[5] = {cexp_m2i_alpha, cexp_mi_alpha, 1.0, cexp_i_alpha, cexp_2i_alpha};
2013 COMPLEX16 d22[5] = {sBetah4, 2.0*cBetah*sBetah3, pPrec->
sqrt6*sBetah2*cBetah2, 2.0*cBetah3*sBetah, cBetah4};
2015 COMPLEX16 d2m2[5] = {d22[4], -d22[3], d22[2], -d22[1], d22[0]};
2019 for(
int m=-2;
m<=2;
m++)
2022 COMPLEX16 A2m2emm = cexp_im_alpha_l2[-
m+2] * d2m2[
m+2] * Y2mA[
m+2];
2023 COMPLEX16 A22emmstar = cexp_im_alpha_l2[
m+2] * d22[
m+2] * conj(Y2mA[
m+2]);
2025 hp_sum += A2m2emm + polarizationSymmetry * A22emmstar;
2026 hc_sum += I*(A2m2emm - polarizationSymmetry * A22emmstar);
2030 if (
l == 2 && mprime == 1){
2033 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2035 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2036 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2038 COMPLEX16 cexp_im_alpha_l2[5] = {cexp_m2i_alpha, cexp_mi_alpha, 1.0, cexp_i_alpha, cexp_2i_alpha};
2043 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};
2045 COMPLEX16 d2m1[5] = {-d21[4], d21[3], -d21[2], d21[1], -d21[0]};
2048 for(
int m=-2;
m<=2;
m++)
2051 COMPLEX16 A2m1emm = cexp_im_alpha_l2[-
m+2] * d2m1[
m+2] * Y2mA[
m+2];
2052 COMPLEX16 A21emmstar = cexp_im_alpha_l2[
m+2] * d21[
m+2] * conj(Y2mA[
m+2]);
2053 hp_sum += A2m1emm + A21emmstar;
2054 hc_sum += I*(A2m1emm - A21emmstar);
2060 if (
l == 3 && mprime == 3){
2063 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2064 COMPLEX16 cexp_3i_alpha = cexp_i_alpha * cexp_2i_alpha;
2066 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2067 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2068 COMPLEX16 cexp_m3i_alpha = cexp_mi_alpha * cexp_m2i_alpha;
2070 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};
2075 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};
2077 COMPLEX16 d3m3[7] = {d33[6], -d33[5], d33[4], -d33[3], d33[2], -d33[1], d33[0]};
2079 for(
int m=-3;
m<=3;
m++)
2082 COMPLEX16 A3m3emm = cexp_im_alpha_l3[-
m+3] * d3m3[
m+3] * Y3mA[
m+3];
2083 COMPLEX16 A33emmstar = cexp_im_alpha_l3[
m+3] * d33[
m+3] * conj(Y3mA[
m+3]);
2084 hp_sum += A3m3emm - A33emmstar;
2085 hc_sum += I*(A3m3emm + A33emmstar);
2090 if (
l == 3 && mprime == 2){
2093 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2094 COMPLEX16 cexp_3i_alpha = cexp_i_alpha * cexp_2i_alpha;
2096 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2097 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2098 COMPLEX16 cexp_m3i_alpha = cexp_mi_alpha * cexp_m2i_alpha;
2100 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};
2105 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};
2107 COMPLEX16 d3m2[7] = {-d32[6], d32[5], -d32[4], d32[3], -d32[2], d32[1], -d32[0]};
2110 for(
int m=-3;
m<=3;
m++)
2113 COMPLEX16 A3m2emm = cexp_im_alpha_l3[-
m+3] * d3m2[
m+3] * Y3mA[
m+3];
2114 COMPLEX16 A32emmstar = cexp_im_alpha_l3[
m+3] * d32[
m+3] * conj(Y3mA[
m+3]);
2115 hp_sum += A3m2emm - A32emmstar;
2116 hc_sum += I*(A3m2emm + A32emmstar);
2122 if (
l == 4 && mprime == 4){
2125 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2126 COMPLEX16 cexp_3i_alpha = cexp_i_alpha * cexp_2i_alpha;
2127 COMPLEX16 cexp_4i_alpha = cexp_i_alpha * cexp_3i_alpha;
2129 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2130 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2131 COMPLEX16 cexp_m3i_alpha = cexp_mi_alpha * cexp_m2i_alpha;
2132 COMPLEX16 cexp_m4i_alpha = cexp_mi_alpha * cexp_m3i_alpha;
2134 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};
2139 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};
2141 COMPLEX16 d4m4[9] = {d44[8], -d44[7], d44[6], -d44[5], d44[4], -d44[3], d44[2], -d44[1], d44[0]};
2143 for(
int m=-4;
m<=4;
m++)
2146 COMPLEX16 A4m4emm = cexp_im_alpha_l4[-
m+4] * d4m4[
m+4] * Y4mA[
m+4];
2147 COMPLEX16 A44emmstar = cexp_im_alpha_l4[
m+4] * d44[
m+4] * conj(Y4mA[
m+4]);
2148 hp_sum += A4m4emm + A44emmstar;
2149 hc_sum += I*(A4m4emm - A44emmstar);
2154 if (
l == 4 && mprime == 3){
2157 COMPLEX16 cexp_2i_alpha = cexp_i_alpha * cexp_i_alpha;
2158 COMPLEX16 cexp_3i_alpha = cexp_i_alpha * cexp_2i_alpha;
2159 COMPLEX16 cexp_4i_alpha = cexp_i_alpha * cexp_3i_alpha;
2161 COMPLEX16 cexp_mi_alpha = 1.0 / cexp_i_alpha;
2162 COMPLEX16 cexp_m2i_alpha = cexp_mi_alpha * cexp_mi_alpha;
2163 COMPLEX16 cexp_m3i_alpha = cexp_mi_alpha * cexp_m2i_alpha;
2164 COMPLEX16 cexp_m4i_alpha = cexp_mi_alpha * cexp_m3i_alpha;
2166 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};
2171 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};
2173 COMPLEX16 d4m3[9] = {-d43[8], d43[7], -d43[6], d43[5], -d43[4], d43[3], -d43[2], d43[1], -d43[0]};
2175 for(
int m=-4;
m<=4;
m++)
2178 COMPLEX16 A4m3emm = cexp_im_alpha_l4[-
m+4] * d4m3[
m+4] * Y4mA[
m+4];
2179 COMPLEX16 A43emmstar = cexp_im_alpha_l4[
m+4] * d43[
m+4] * conj(Y4mA[
m+4]);
2180 hp_sum += A4m3emm + A43emmstar;
2181 hc_sum += I*(A4m3emm - A43emmstar);
2189 eps_phase_hP_lmprime = cexp(-1.*mprime*I*epsilon) * hlmprime / 2.0;
2192 COMPLEX16 exp_imprime_epsilon = cexp_i_epsilon;
2195 exp_imprime_epsilon *= cexp_i_epsilon;
2197 eps_phase_hP_lmprime = 1./exp_imprime_epsilon * hlmprime / 2.0;
2202 *hp += eps_phase_hP_lmprime * hp_sum;
2203 *hc += eps_phase_hP_lmprime * hc_sum;
2212 sprintf(fileSpec,
"angles_hphc_%i%i.dat",
l, mprime);
2216 sprintf(fileSpec,
"angles_hphc_MB_%i%i.dat",
l, mprime);
2218 fileangle = fopen(fileSpec,
"a");
2306 const REAL8 distance,
2307 const REAL8 inclination,
2312 const REAL8 fRef_In,
2324 printf(
"fRef_In : %e\n",fRef_In);
2325 printf(
"m1_SI : %e\n",m1_SI);
2326 printf(
"m2_SI : %e\n",m2_SI);
2327 printf(
"chi1_l : %e\n",chi1z);
2328 printf(
"chi2_l : %e\n",chi2z);
2329 printf(
"phiRef : %e\n",phiRef);
2331 printf(
"Performing sanity checks...\n");
2337 XLAL_CHECK(fRef_In >= 0,
XLAL_EFUNC,
"Error: fRef_In must be positive or set to 0 to ignore. \n");
2343 XLAL_CHECK(distance > 0,
XLAL_EFUNC,
"Error: Distance must be positive and greater than 0. \n");
2357 mass_ratio = m1_SI / m2_SI;
2361 mass_ratio = m2_SI / m1_SI;
2363 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"); }
2364 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"); }
2365 if(fabs(chi1z) > 0.99 || fabs(chi2z) > 0.99) {
XLAL_PRINT_WARNING(
"Warning: Extrapolating to extremal spins, model is not trusted.\n"); }
2368 REAL8 fRef = (fRef_In == 0.0) ?
f_min : fRef_In;
2371 LALDict *lalParams_aux;
2373 if (lalParams == NULL)
2384 printf(
"\n\n **** Initializing waveform struct... **** \n\n");
2395 status =
IMRPhenomXSetWaveformVariables(pWF, m1_SI, m2_SI, chi1z, chi2z, deltaF, fRef, phiRef,
f_min,
f_max, distance, inclination, lalParams_aux,
PHENOMXDEBUG);
2408 printf(
"\n\n **** Initializing precession struct... **** \n\n");
2417 if(pflag==310||pflag==311||pflag==320||pflag==321){
2447 XLAL_PRINT_WARNING(
"The L0Frame option only works near the AS limit, it should not be used otherwise.");
2467 printf(
"\n\n **** Calling IMRPhenomXPHM_OneMode... **** \n\n");
2490 for(
UINT4 i = 0;
i<(*hlmpos)->data->length;
i++)
2492 (*hlmpos)->data->data[
i] *= shiftpos;
2493 (*hlmneg)->data->data[
i] *= shiftneg;
2501 printf(
"\n\n **** Call to IMRPhenomXPHM_OneMode complete. **** \n\n");
2510 lastfreq = pWF->
fMax;
2511 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);
2517 size_t n_full =
NextPow2(lastfreq / deltaF) + 1;
2518 size_t n = (*hlmpos)->data->length;
2522 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 );
2526 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 );
2538 gsl_interp_accel_free(pPrec->
alpha_acc);
2539 gsl_interp_accel_free(pPrec->
gamma_acc);
2573 const REAL8 distance,
2574 const REAL8 inclination,
2576 const REAL8 fRef_In,
2588 printf(
"fRef_In : %e\n",fRef_In);
2589 printf(
"m1_SI : %e\n",m1_SI);
2590 printf(
"m2_SI : %e\n",m2_SI);
2591 printf(
"chi1_l : %e\n",chi1z);
2592 printf(
"chi2_l : %e\n",chi2z);
2593 printf(
"phiRef : %e\n",phiRef);
2595 printf(
"Performing sanity checks...\n");
2601 XLAL_CHECK(fRef_In >= 0,
XLAL_EFUNC,
"Error: fRef_In must be positive or set to 0 to ignore. \n");
2604 XLAL_CHECK(distance > 0,
XLAL_EFUNC,
"Error: Distance must be positive and greater than 0. \n");
2621 mass_ratio = m1_SI / m2_SI;
2625 mass_ratio = m2_SI / m1_SI;
2627 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"); }
2628 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"); }
2629 if(fabs(chi1z) > 0.99 || fabs(chi2z) > 0.99) {
XLAL_PRINT_WARNING(
"Warning: Extrapolating to extremal spins, model is not trusted.\n"); }
2632 REAL8 fRef = (fRef_In == 0.0) ?
f_min : fRef_In;
2635 LALDict *lalParams_aux;
2637 if (lalParams == NULL)
2649 printf(
"\n\n **** Initializing waveform struct... **** \n\n");
2660 status =
IMRPhenomXSetWaveformVariables(pWF, m1_SI, m2_SI, chi1z, chi2z, 0.0, fRef, phiRef,
f_min,
f_max, distance, inclination, lalParams_aux,
PHENOMXDEBUG);
2665 printf(
"\n\n **** Initializing precession struct... **** \n\n");
2674 if(pflag==310||pflag==311||pflag==320||pflag==321){
2704 XLAL_PRINT_WARNING(
"The L0Frame option only works near the AS limit, it should not be used otherwise.");
2723 printf(
"\n\n **** Calling IMRPhenomXPHM_OneMode... **** \n\n");
2749 for(
UINT4 i = 0;
i<(*hlmpos)->data->length;
i++)
2751 (*hlmpos)->data->data[
i] *= shiftpos;
2752 (*hlmneg)->data->data[
i] *= shiftneg;
2760 printf(
"\n\n **** Call to IMRPhenomXPHM_OneMode complete. **** \n\n");
2774 gsl_interp_accel_free(pPrec->
alpha_acc);
2775 gsl_interp_accel_free(pPrec->
gamma_acc);
2821 if (ModeArray == NULL)
2827 bool mode_arrays_consistent =
false;
2829 while (mode_arrays_consistent ==
false && emm<=(
INT4)ell){
2831 mode_arrays_consistent =
true;
2835 if(mode_arrays_consistent ==
false){
2836 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);
2846 size_t npts = (*hlmpos)->data->length;
2848 XLAL_CHECK (*hlmneg,
XLAL_ENOMEM,
"Failed to allocated waveform COMPLEX16FrequencySeries of length %zu.", npts);
2849 memset((*hlmneg)->data->data, 0, npts *
sizeof(
COMPLEX16));
2866 UINT4 n_coprec_modes = 0;
2874 REAL8 Mf_RD_lm = 0.0;
2876 if (IMRPhenomXPNRUseTunedAngles){
2880 if (!hm_angle_spline)
2901 "Error: IMRPhenomX_PNR_RemapThetaJSF failed in IMRPhenomX_PNR_GeneratePNRAngles.");
2908 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
2916 for (
UINT4 emmprime = 1; emmprime <= ell; emmprime++)
2937 printf(
"\n*************************************************\n Non-precessing Mode %i%i\n************************************",ell, emmprime);
2944 if (thresholdMB == 0){
2945 if(ell == 2 && emmprime == 2)
2957 if(ell==3 && emmprime==2){
2979 if(ell==2 && emmprime==2)
2981 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
2993 && ((*hlmneg)->data->length==htildelm->
data->
length),
2995 "Inconsistent lengths between frequency series htildelm (%d), hlmpos (%d) and hlmneg (%d).",
2996 htildelm->
data->
length, (*hlmpos)->data->length, (*hlmneg)->data->length
3000 if((pWF->
q == 1) && (pWF->
chi1L == pWF->
chi2L) && (emmprime % 2 != 0))
3018 hlmcoprec = htildelm->
data->
data[idx + offset];
3019 if(
m < 0) (*hlmpos)->data->data[idx + offset] = hlmcoprec;
3020 if(
m > 0) (*hlmneg)->data->data[idx + offset] = hlmcoprec;
3026 REAL8 Mf_high = 0.0;
3031 if (IMRPhenomXPNRUseTunedAngles){
3033 if((ell==2)&&(emmprime==2))
3053 hlmcoprec = htildelm->
data->
data[idx + offset];
3056 if(ell == 2 && emmprime == 2 && AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
3058 hlmcoprec_antiSym = antiSym_amp->
data[idx]*cexp(I*antiSym_phi->
data[idx]);
3064 if(IMRPhenomXPNRUseTunedAngles)
3080 (*hlmpos)->data->data[idx + offset] += hlm->
data[0];
3081 (*hlmneg)->data->data[idx + offset] += hlm->
data[1];
3085 if(IMRPhenomXPNRUseTunedAngles)
3087 gsl_interp_accel_reset(hm_angle_spline->
alpha_acc);
3088 gsl_interp_accel_reset(hm_angle_spline->
beta_acc);
3089 gsl_interp_accel_reset(hm_angle_spline->
gamma_acc);
3096 if (IMRPhenomXPNRUseTunedAngles){
3101 gsl_interp_accel_free(hm_angle_spline->
alpha_acc);
3102 gsl_interp_accel_free(hm_angle_spline->
beta_acc);
3103 gsl_interp_accel_free(hm_angle_spline->
gamma_acc);
3109 if(n_coprec_modes == 0)
3111 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);
3121 if (AntisymmetricWaveform && IMRPhenomXPNRUseTunedAngles)
3129 printf(
"\n******Leaving IMRPhenomXPHM_OneMode*****\n");
3158 double epsilon = 0.0;
3160 double cBetah = 0.0;
3161 double sBetah = 0.0;
3193 const double v = cbrt(
LAL_PI * Mf * (2.0/mprime) );
3195 double cos_beta = 0.0;
3197 REAL8 alpha_offset_mprime = 0, epsilon_offset_mprime = 0;
3200 alpha = vangles.
x - alpha_offset_mprime;
3201 epsilon = vangles.
y - epsilon_offset_mprime;
3202 cos_beta = vangles.
z;
3223 REAL8 Mfprime = Mf * (2.0 / mprime);
3225 if(Mfprime< pPrec->ftrans_MRD)
3231 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);
3246 REAL8 deltagamma=0.;
3266 alpha = alpha_i- alpha_offset_mprime;
3267 epsilon = -
gamma - epsilon_offset_mprime;
3277 XLAL_ERROR(
XLAL_EINVAL,
"Error. IMRPhenomXPrecVersion not recognized. Recommended default is 223.\n");
3285 REAL8 cBetah2 = cBetah * cBetah;
3286 REAL8 cBetah3 = cBetah * cBetah2;
3287 REAL8 cBetah4 = cBetah * cBetah3;
3288 REAL8 cBetah5 = cBetah * cBetah4;
3289 REAL8 cBetah6 = cBetah * cBetah5;
3290 REAL8 cBetah7 = cBetah * cBetah6;
3291 REAL8 cBetah8 = cBetah * cBetah7;
3293 REAL8 sBetah2 = sBetah * sBetah;
3294 REAL8 sBetah3 = sBetah * sBetah2;
3295 REAL8 sBetah4 = sBetah * sBetah3;
3296 REAL8 sBetah5 = sBetah * sBetah4;
3297 REAL8 sBetah6 = sBetah * sBetah5;
3298 REAL8 sBetah7 = sBetah * sBetah6;
3299 REAL8 sBetah8 = sBetah * sBetah7;
3310 if (
l == 2 && mprime == 2){
3312 COMPLEX16 d22[5] = {sBetah4, 2.0*cBetah*sBetah3, pPrec->
sqrt6*sBetah2*cBetah2, 2.0*cBetah3*sBetah, cBetah4};
3314 COMPLEX16 d2m2[5] = {d22[4], -d22[3], d22[2], -d22[1], d22[0]};
3318 hlm += cexp_im_alpha * d2m2[
m+2];
3319 hlmneg += cexp_im_alpha * d22[
m+2];
3323 if (
l == 2 && mprime == 1){
3325 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};
3327 COMPLEX16 d2m1[5] = {-d21[4], d21[3], -d21[2], d21[1], -d21[0]};
3331 hlm += cexp_im_alpha * d2m1[
m+2];
3332 hlmneg += cexp_im_alpha * d21[
m+2];
3336 if (
l == 3 && mprime == 3){
3339 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};
3341 COMPLEX16 d3m3[7] = {d33[6], -d33[5], d33[4], -d33[3], d33[2], -d33[1], d33[0]};
3345 hlm += cexp_im_alpha * d3m3[
m+3];
3346 hlmneg += cexp_im_alpha * d33[
m+3];
3350 if (
l == 3 && mprime == 2){
3353 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};
3355 COMPLEX16 d3m2[7] = {-d32[6], d32[5], -d32[4], d32[3], -d32[2], d32[1], -d32[0]};
3359 hlm += cexp_im_alpha * d3m2[
m+3];
3360 hlmneg += cexp_im_alpha * d32[
m+3];
3364 if (
l == 4 && mprime == 4){
3366 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};
3368 COMPLEX16 d4m4[9] = {d44[8], -d44[7], d44[6], -d44[5], d44[4], -d44[3], d44[2], -d44[1], d44[0]};
3372 hlm += cexp_im_alpha * d4m4[
m+4];
3373 hlmneg += cexp_im_alpha * d44[
m+4];
3380 COMPLEX16 exp_imprime_epsilon = cexp(mprime*I*epsilon);
3382 eps_phase_hP_lmprime = 1./exp_imprime_epsilon * (hlmprime + hlmprime_antisym);
3383 eps_phase_hP_lmprime_neg = exp_imprime_epsilon * minus1l * conj(hlmprime - hlmprime_antisym);
3386 (hlminertial)->
data[0] = eps_phase_hP_lmprime * hlm;
3387 (hlminertial)->
data[1] = eps_phase_hP_lmprime_neg * hlmneg;
3420 LALValue *ModeArrayJframe = NULL;
3423 LALDict *lalParams_aux;
3425 if (lalParams == NULL)
3441 if(ModeArrayJframe == NULL)
3470 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);
3498 for (
INT4 i = -length;
i<=length;
i++)
3500 freqs->
data[
i+length] =
i*deltaF;
3525 INT4 lalParams_In = 0;
3526 if (lalParams == NULL)
3534 if (ModeArray == NULL)
3537 XLAL_PRINT_INFO(
"Using default non-precessing modes for IMRPhenomXPHM: 2|2|, 2|1|, 3|3|, 3|2|, 4|4|.\n");
3553 else {
XLAL_PRINT_INFO(
"Using custom non-precessing modes for PhenomXPHM.\n"); }
3556 if(lalParams_In == 1)
3570 for(
INT4 emm=0; emm<=ell; emm++)
3586 REAL8 *alpha_offset_mprime,
3587 REAL8 *epsilon_offset_mprime,
3643 double omega =
LAL_PI * Mf *2./mprime;
3644 double logomega = log(omega);
3645 double omega_cbrt = cbrt(omega);
3646 double omega_cbrt2 = omega_cbrt * omega_cbrt;
3648 REAL8 alpha_offset_mprime = 0., epsilon_offset_mprime = 0.;
3654 + pPrec->
alpha2 / omega_cbrt2
3655 + pPrec->
alpha3 / omega_cbrt
3657 + pPrec->
alpha5 * omega_cbrt
3658 - alpha_offset_mprime
3667 - epsilon_offset_mprime
3700 size_t iStart = (size_t) (pWF->
fMin / pWF->
deltaF);
3706 REAL8 dfpower = 11./6.;
3712 REAL8 MfMECO, MfLorentzianEnd;
3713 REAL8 dfmerger = 0., dfringdown = 0.;
3714 UINT4 lengthallGrids = 20;
3728 if(ell == 2 && emmprime ==2){
3729 MfMECO = pWF->
fMECO;
3731 printf(
"\nfRING = %e\n",pWF->
fRING);
3732 printf(
"fDAMP = %e\n",pWF->
fDAMP);
3733 printf(
"alphaL22 = %.16e", pPhase22->
cLovfda/pWF->
eta);
3763 MfLorentzianEnd = pWFHM->
fRING + 2*pWFHM->
fDAMP;
3765 printf(
"\nfRING = %e\n",pWFHM->
fRING);
3766 printf(
"fDAMP = %e\n",pWFHM->
fDAMP);
3767 printf(
"alphaL = %.16e", pPhase->
alphaL);
3778 if (allGrids == NULL)
3781 printf(
"Malloc of allGrids failed!\n");
3782 printf(
"nGridsUsed = %i\n", nGridsUsed);
3789 UINT4 actualnumberofGrids = 0;
3791 UINT4 lenCoarseArray = 0;
3795 for(
UINT4 kk = 0; kk < nGridsUsed; kk++){
3796 lenCoarseArray = lenCoarseArray + allGrids[kk].
Length;
3797 actualnumberofGrids++;
3800 printf(
"\nkk = %i\n",kk);
3801 printf(
"xStart: %.16e\n", allGrids[kk].xStart);
3802 printf(
"xEnd: %.16e\n", allGrids[kk].xEndRequested);
3803 printf(
"Length: %i\n", allGrids[kk].Length);
3804 printf(
"deltax: %.16e\n", allGrids[kk].deltax);
3805 printf(
"evaldMf: %.16e\n", evaldMf);
3806 printf(
"xMax: %.16e\n", allGrids[kk].xMax);
3807 printf(
"Last grid.xMax = %.16f\n", allGrids[actualnumberofGrids-1].xMax);
3810 if(allGrids[kk].xMax + evaldMf >= Mfmax){
3816 while(allGrids[actualnumberofGrids-1].xMax < Mfmax){
3817 allGrids[actualnumberofGrids-1].
xMax = allGrids[actualnumberofGrids-1].
xMax + allGrids[actualnumberofGrids-1].
deltax;
3818 allGrids[actualnumberofGrids-1].
Length = allGrids[actualnumberofGrids-1].
Length + 1;
3823 printf(
"\nactualnumberofGrids = %i\n", actualnumberofGrids);
3824 printf(
"lenCoarseArray = %i\n", lenCoarseArray);
3825 printf(
"Last grid.xMax = %.16f", allGrids[actualnumberofGrids-1].xMax);
3833 UINT4 lencoarseFreqs = 0;
3835 for(
UINT4 kk = 0; kk < actualnumberofGrids; kk++){
3836 for(
INT4 ll = 0; ll < allGrids[kk].
Length; ll++){
3837 (*coarseFreqs)->data[lencoarseFreqs] = (allGrids[kk].
xStart + allGrids[kk].
deltax*ll);
3845 printf(
"\n******** Coarse frequencies array done ********* \n");
3846 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));
3851 return actualnumberofGrids;
void XLALDestroyDict(LALDict *dict)
LALDict * XLALDictDuplicate(LALDict *old)
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 * XLALResizeCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series, int first, size_t length)
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, 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 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.
void XLALDestroyREAL8Sequence(REAL8Sequence *sequence)
void XLALDestroyCOMPLEX16Sequence(COMPLEX16Sequence *sequence)
REAL8Sequence * XLALCreateREAL8Sequence(size_t length)
COMPLEX16Sequence * XLALCreateCOMPLEX16Sequence(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
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 alpha5
Coefficient of .
REAL8 alpha2
Coefficient of .