24#define UNUSED __attribute__ ((unused))
40#include <gsl/gsl_errno.h>
41#include <gsl/gsl_bspline.h>
42#include <gsl/gsl_blas.h>
43#include <gsl/gsl_min.h>
44#include <gsl/gsl_spline.h>
45#include <gsl/gsl_poly.h>
47#include <lal/SeqFactories.h>
48#include <lal/LALConstants.h>
49#include <lal/XLALError.h>
50#include <lal/FrequencySeries.h>
52#include <lal/StringInput.h>
53#include <lal/Sequence.h>
54#include <lal/LALStdio.h>
55#include <lal/FileIO.h>
56#include <lal/LALSimSphHarmMode.h>
57#include <lal/LALDatatypes.h>
58#include <lal/LALSimInspiral.h>
59#include <lal/AVFactories.h>
60#include <lal/SphericalHarmonics.h>
64#define f_hyb_ini 0.003
65#define f_hyb_end 0.004
67#ifdef LAL_HDF5_ENABLED
68#include <lal/H5FileIO.h>
69static const char ROMDataHDF5[] =
"SEOBNRv4HMROM_v1.0.hdf5";
72#include <lal/LALSimInspiral.h>
73#include <lal/LALSimIMR.h>
78#include <lal/LALConfig.h>
79#ifdef LAL_PTHREAD_LOCK
85#ifdef LAL_PTHREAD_LOCK
86static pthread_once_t SEOBNRv4HMROM_is_initialized = PTHREAD_ONCE_INIT;
116#define Mf_low_22 0.0004925491025543576
117#define Mf_low_33 (Mf_low_22 * (3.0/2.0))
118#define Mf_low_21 (Mf_low_22 * (1.0/2.0))
119#define Mf_low_44 (Mf_low_22 * (4.0/2.0))
120#define Mf_low_55 (Mf_low_22 * (5.0/2.0))
125typedef struct tagSEOBNRROMdataDS_coeff
157 SEOBNRROMdataDS_submodel*
hqhs;
158 SEOBNRROMdataDS_submodel*
hqls;
159 SEOBNRROMdataDS_submodel*
lqhs;
160 SEOBNRROMdataDS_submodel*
lqls;
161 SEOBNRROMdataDS_submodel*
lowf;
167typedef int (*
load_dataPtr)(
const char*, gsl_vector *, gsl_vector *, gsl_matrix *, gsl_matrix *, gsl_vector *);
169typedef struct tagSplineData
171 gsl_bspline_workspace *bwx;
172 gsl_bspline_workspace *bwy;
173 gsl_bspline_workspace *bwz;
176typedef struct tagAmpPhaseSplineData
194 UNUSED SEOBNRROMdataDS_submodel **submodel,
195 UNUSED
const char dir[],
196 UNUSED
const char grp_name[],
207 const double *chi1vec,
208 const double *chi2vec
238UNUSED
static double GetModeAmpFactor(
double eta,
double delta,
double chi1,
double chi2,
int l,
int m,
double v);
275static size_t NextPow2(
const size_t n);
301 const double *chi1vec,
302 const double *chi2vec,
318 REAL8* Deltaphi_align,
319 gsl_vector *phase_lo,
320 gsl_vector *phase_hi,
330 gsl_vector *phase_lo,
331 gsl_vector *phase_hi,
336 REAL8 Deltat_22_align,
337 REAL8 Deltaphi_22_align,
353 gsl_spline **hyb_spline,
362 gsl_spline **hyb_spline,
364 REAL8* Deltaphi_align,
367 gsl_vector *PN_phase,
373 gsl_spline **hyb_spline,
376 gsl_vector *PN_phase,
379 REAL8 Deltat_22_align,
380 REAL8 Deltaphi_22_align,
397 UNUSED
REAL8 distance,
398 UNUSED
REAL8 Mtot_sec,
420 *
x = gsl_vector_alloc(
s->size);
421 *
y = gsl_vector_alloc(
s->size);
422 for (
size_t i=0;
i <
s->size;
i++) {
423 gsl_vector_set(*
x,
i,
s->x[
i]);
424 gsl_vector_set(*
y,
i,
s->y[
i]);
441#ifdef LAL_HDF5_ENABLED
442#define datafile ROMDataHDF5
446 "Unable to resolve data file '%s' in $LAL_DATA_PATH.\n"
447 "Note: LALSuite versions >= 7.25 require data files that are publicly available at:\n"
448 "https://git.ligo.org/waveforms/software/lalsuite-waveform-data\n"
449 "and on Zenodo at: https://zenodo.org/records/14999310.\n"
450 "For earlier LALSuite versions, use the files in lalsuite-extra, available at:\n"
451 "https://git.ligo.org/lscsoft/lalsuite-extra\n",
454 char *dir = dirname(
path);
461 files in $LAL_DATA_PATH for the mode = %d\n",
i);
486 const double *chi1vec,
487 const double *chi2vec
490 if(!splinedata) exit(1);
496 const size_t nbreak_x = ncx-2;
497 const size_t nbreak_y = ncy-2;
498 const size_t nbreak_z = ncz-2;
501 gsl_bspline_workspace *bwx = gsl_bspline_alloc(4, nbreak_x);
502 gsl_bspline_workspace *bwy = gsl_bspline_alloc(4, nbreak_y);
503 gsl_bspline_workspace *bwz = gsl_bspline_alloc(4, nbreak_z);
506 gsl_vector *breakpts_x = gsl_vector_alloc(nbreak_x);
507 gsl_vector *breakpts_y = gsl_vector_alloc(nbreak_y);
508 gsl_vector *breakpts_z = gsl_vector_alloc(nbreak_z);
510 gsl_vector_set(breakpts_x,
i, qvec[
i]);
511 for (
UINT4 j=0; j<nbreak_y; j++)
512 gsl_vector_set(breakpts_y, j, chi1vec[j]);
513 for (
UINT4 k=0; k<nbreak_z; k++)
514 gsl_vector_set(breakpts_z, k, chi2vec[k]);
516 gsl_bspline_knots(breakpts_x, bwx);
517 gsl_bspline_knots(breakpts_y, bwy);
518 gsl_bspline_knots(breakpts_z, bwz);
520 gsl_vector_free(breakpts_x);
521 gsl_vector_free(breakpts_y);
522 gsl_vector_free(breakpts_z);
524 (*splinedata)->bwx=bwx;
525 (*splinedata)->bwy=bwy;
526 (*splinedata)->bwz=bwz;
532 if(!splinedata)
return;
533 if(splinedata->
bwx) gsl_bspline_free(splinedata->
bwx);
534 if(splinedata->
bwy) gsl_bspline_free(splinedata->
bwy);
535 if(splinedata->
bwz) gsl_bspline_free(splinedata->
bwz);
549 for (
int i=0;
i<num_modes;
i++) {
557 if(!data_array)
return;
560 for (
int i=0;
i<num_modes;
i++) {
561 data = data_array[
i];
565 if (
data->spline_amp) gsl_spline_free(
data->spline_amp);
566 if (
data->spline_phi) gsl_spline_free(
data->spline_phi);
567 if (
data->acc_amp) gsl_interp_accel_free(
data->acc_amp);
568 if (
data->acc_phi) gsl_interp_accel_free(
data->acc_phi);
569 if (
data->f) gsl_vector_free(
data->f);
590 const double *chi1vec,
591 const double *chi2vec,
596 XLAL_ERROR(
XLAL_EDOM,
"Truncation parameter nk_max %d must be smaller or equal to nk %d\n", nk_max, nk);
605 gsl_bspline_workspace *bwx=splinedata->
bwx;
606 gsl_bspline_workspace *bwy=splinedata->
bwy;
607 gsl_bspline_workspace *bwz=splinedata->
bwz;
611 for (
int k=0; k<nk; k++) {
612 gsl_vector v = gsl_vector_subvector(cvec, k*
N,
N).vector;
614 gsl_vector_set(c_out, k, csum);
641 UNUSED SEOBNRROMdataDS *romdata,
642 UNUSED
const char dir[],
643 UNUSED
UINT4 index_mode)
649 XLALPrintError(
"WARNING: You tried to setup the SEOBNRv4HMROM model that was already initialised. Ignoring\n");
653#ifdef LAL_HDF5_ENABLED
655 size_t size = strlen(dir) + strlen(ROMDataHDF5) + 2;
657 snprintf(
path, size,
"%s/%s", dir, ROMDataHDF5);
661 PrintInfoStringAttribute(
file,
"Email");
662 PrintInfoStringAttribute(
file,
"Description");
663 ret = ROM_check_canonical_file_basename(
file,ROMDataHDF5,
"CANONICAL_FILE_BASENAME");
702 (romdata)->hqhs = NULL;
705 (romdata)->hqls = NULL;
708 (romdata)->lqhs = NULL;
711 (romdata)->lqls = NULL;
714 (romdata)->lowf = NULL;
720 if(submodel->cvec_real) gsl_vector_free(submodel->cvec_real);
721 if(submodel->cvec_imag) gsl_vector_free(submodel->cvec_imag);
722 if(submodel->cvec_phase) gsl_vector_free(submodel->cvec_phase);
723 if(submodel->Breal) gsl_matrix_free(submodel->Breal);
724 if(submodel->Bimag) gsl_matrix_free(submodel->Bimag);
725 if(submodel->Bphase) gsl_matrix_free(submodel->Bphase);
726 if(submodel->gCMode) gsl_vector_free(submodel->gCMode);
727 if(submodel->gPhase) gsl_vector_free(submodel->gPhase);
728 if(submodel->qvec) gsl_vector_free(submodel->qvec);
729 if(submodel->chi1vec) gsl_vector_free(submodel->chi1vec);
730 if(submodel->chi2vec) gsl_vector_free(submodel->chi2vec);
735 SEOBNRROMdataDS_submodel **submodel,
736 UNUSED
const char dir[],
737 UNUSED
const char grp_name[],
738 UNUSED
UINT4 index_mode
741 if(!submodel) exit(1);
744 *submodel =
XLALCalloc(1,
sizeof(SEOBNRROMdataDS_submodel));
748#ifdef LAL_HDF5_ENABLED
749 size_t size = strlen(dir) + strlen(ROMDataHDF5) + 2;
751 snprintf(
path, size,
"%s/%s", dir, ROMDataHDF5);
760 ReadHDF5RealVectorDataset(sub, path_to_dataset, & (*submodel)->cvec_real);
761 free(path_to_dataset);
763 ReadHDF5RealVectorDataset(sub, path_to_dataset, & (*submodel)->cvec_imag);
764 free(path_to_dataset);
768 ReadHDF5RealVectorDataset(sub,
"phase_carrier/coeff_flattened", & (*submodel)->cvec_phase);
776 ReadHDF5RealMatrixDataset(sub, path_to_dataset, & (*submodel)->Breal);
777 free(path_to_dataset);
779 ReadHDF5RealMatrixDataset(sub, path_to_dataset, & (*submodel)->Bimag);
780 free(path_to_dataset);
784 ReadHDF5RealMatrixDataset(sub,
"phase_carrier/basis", & (*submodel)->Bphase);
790 ReadHDF5RealVectorDataset(sub, path_to_dataset, & (*submodel)->gCMode);
791 free(path_to_dataset);
795 ReadHDF5RealVectorDataset(sub,
"phase_carrier/MF_grid", & (*submodel)->gPhase);
798 ReadHDF5RealVectorDataset(sub,
"qvec", & (*submodel)->qvec);
799 ReadHDF5RealVectorDataset(sub,
"chi1vec", & (*submodel)->chi1vec);
800 ReadHDF5RealVectorDataset(sub,
"chi2vec", & (*submodel)->chi2vec);
804 (*submodel)->nk_cmode = (*submodel)->gCMode->size;
807 (*submodel)->nk_phase = (*submodel)->gPhase->size;
809 (*submodel)->ncx = (*submodel)->qvec->size + 2;
810 (*submodel)->ncy = (*submodel)->chi1vec->size + 2;
811 (*submodel)->ncz = (*submodel)->chi2vec->size + 2;
814 (*submodel)->q_bounds[0] = gsl_vector_get((*submodel)->qvec, 0);
815 (*submodel)->q_bounds[1] = gsl_vector_get((*submodel)->qvec, (*submodel)->qvec->size - 1);
816 (*submodel)->chi1_bounds[0] = gsl_vector_get((*submodel)->chi1vec, 0);
817 (*submodel)->chi1_bounds[1] = gsl_vector_get((*submodel)->chi1vec, (*submodel)->chi1vec->size - 1);
818 (*submodel)->chi2_bounds[0] = gsl_vector_get((*submodel)->chi2vec, 0);
819 (*submodel)->chi2_bounds[1] = gsl_vector_get((*submodel)->chi2vec, (*submodel)->chi2vec->size - 1);
834 if(!romdatacoeff) exit(1);
841 (*romdatacoeff)->c_real = gsl_vector_alloc(nk_cmode);
842 (*romdatacoeff)->c_imag = gsl_vector_alloc(nk_cmode);
843 (*romdatacoeff)->c_phase = gsl_vector_alloc(nk_phase);
848 if(romdatacoeff->
c_real) gsl_vector_free(romdatacoeff->
c_real);
849 if(romdatacoeff->
c_imag) gsl_vector_free(romdatacoeff->
c_imag);
856 return 1 << (size_t) ceil(log2(n));
861 gsl_vector *phase_f_lo = gsl_vector_alloc(freq_lo->size);
862 gsl_vector *phase_f_hi = gsl_vector_alloc(freq_hi->size);
878 gsl_vector_free(phase_f_lo);
879 gsl_vector_free(phase_f_hi);
894 "Error setting up SEOBNRv4ROM data - check your $LAL_DATA_PATH\n");
897 UNUSED
UINT4 retcode=0;
900 SEOBNRROMdataDS_submodel *submodel_hi;
901 SEOBNRROMdataDS_submodel *submodel_lo;
905 submodel_lo = romdata->lowf;
909 submodel_hi = romdata->hqls;
911 else if(flag_patch == 1){
912 submodel_hi = romdata->hqhs;
914 else if(flag_patch == 2){
915 submodel_hi = romdata->lqls;
917 else if(flag_patch == 3){
918 submodel_hi = romdata->lqhs;
922 XLALPrintError(
"XLAL Error - %s: SEOBNRv4HM not currently available in this region!\n",
932 gsl_vector* freq_lo = gsl_vector_alloc(submodel_lo->nk_phase);
933 for(
unsigned int i = 0;
i < freq_lo->size;
i++){
934 freq_lo->data[
i] = submodel_lo->gPhase->data[
i];
936 gsl_vector* freq_hi = gsl_vector_alloc(submodel_hi->nk_phase);
943 for(
unsigned int i = 0;
i < freq_hi->size;
i++){
944 freq_hi->data[
i] = inv_scaling*submodel_hi->gPhase->data[
i];
950 *freq = gsl_vector_alloc(i_max_LF + freq_hi->size - i_min_HF + 1);
953 *phase = gsl_vector_calloc((*freq)->size);
956 for(
unsigned int i = 0;
i <= i_max_LF;
i++){
957 (*freq)->data[
i] = freq_lo->data[
i];
959 for(
unsigned int i = i_min_HF;
i < freq_hi->size;
i++){
960 (*freq)->data[i_max_LF+
i-i_min_HF+1] = freq_hi->data[
i];
968 gsl_vector_free(freq_lo);
969 gsl_vector_free(freq_hi);
982 REAL8* Deltaphi_align,
983 gsl_vector *phase_lo,
984 gsl_vector *phase_hi,
1002 *freq = gsl_vector_alloc(i_max_LF + freq_hi->size - i_min_HF + 1);
1005 for(
unsigned int i=0;
i <= i_max_LF;
i++)
1006 (*freq)->data[
i] = freq_lo->data[
i];
1007 for(
unsigned int i=i_min_HF; i < freq_hi->size;
i++)
1008 (*freq)->data[i_max_LF+
i-i_min_HF+1] = freq_hi->data[
i];
1011 *phase = gsl_vector_calloc((*freq)->size);
1016 REAL8 Deltaphi = 0.;
1017 retcode =
align_wfs_window(freq_lo, freq_hi, phase_lo, phase_hi, &Deltat, &Deltaphi, f_hyb_lo, f_hyb_hi);
1021 retcode =
blend_functions(*freq, *phase, freq_lo, phase_lo, freq_hi, phase_hi, f_hyb_lo, f_hyb_hi);
1027 *Deltat_align = Deltat;
1028 *Deltaphi_align = Deltaphi;
1037 gsl_vector *phase_lo,
1038 gsl_vector *phase_hi,
1039 gsl_vector *freq_lo,
1040 gsl_vector *freq_hi,
1043 REAL8 Deltat_22_align,
1044 REAL8 Deltaphi_22_align,
1059 *freq = gsl_vector_alloc(i_max_LF + freq_hi->size - i_min_HF + 1);
1062 for(
unsigned int i=0;
i <= i_max_LF;
i++)
1063 (*freq)->data[
i] = freq_lo->data[
i];
1064 for(
unsigned int i=i_min_HF; i < freq_hi->size;
i++)
1065 (*freq)->data[i_max_LF+
i-i_min_HF+1] = freq_hi->data[
i];
1068 *phase = gsl_vector_calloc((*freq)->size);
1071 retcode =
align_wfs_window_from_22(freq_lo, freq_hi, phase_lo, phase_hi, f_hyb_lo, f_hyb_hi, Deltat_22_align, Deltaphi_22_align, modeM);
1075 retcode =
blend_functions(*freq, *phase, freq_lo, phase_lo, freq_hi, phase_hi, f_hyb_lo, f_hyb_hi);
1087 gsl_vector *freq_lo,
1088 gsl_vector *freq_hi,
1103 *freq = gsl_vector_alloc(i_max_LF + freq_hi->size - i_min_HF + 1);
1106 for(
unsigned int i=0;
i <= i_max_LF;
i++)
1107 (*freq)->data[
i] = freq_lo->data[
i];
1108 for(
unsigned int i=i_min_HF; i < freq_hi->size;
i++)
1109 (*freq)->data[i_max_LF+
i-i_min_HF+1] = freq_hi->data[
i];
1112 *amp = gsl_vector_calloc((*freq)->size);
1115 retcode =
blend_functions(*freq, *amp, freq_lo, amp_lo, freq_hi, amp_hi, f_hyb_lo, f_hyb_hi);
1130 REAL8 f_max_carrier = freq_carrier_hyb->data[freq_carrier_hyb->size -1];
1131 REAL8 phase_carrier_at_f_max = phase_carrier_hyb->data[phase_carrier_hyb->size -1];
1133 gsl_interp_accel *acc = gsl_interp_accel_alloc ();
1134 gsl_spline *spline = gsl_spline_alloc (gsl_interp_cspline, phase_carrier_hyb->size);
1136 gsl_spline_init (spline, freq_carrier_hyb->data, phase_carrier_hyb->data, phase_carrier_hyb->size);
1137 REAL8 der_phase_carrier_at_f_max = gsl_spline_eval_deriv(spline, f_max_carrier, acc);
1142 for(
unsigned int i = 0;
i < freq_mode_lm->size;
i++){
1143 if(freq_mode_lm->data[
i]/(
REAL8)modeM < f_max_carrier){
1145 phase_approx_lm->data[
i] = (
REAL8)modeM*gsl_spline_eval (spline, freq_mode_lm->data[
i]/(
REAL8)modeM, acc) + const_phase_shift;
1149 phase_approx_lm->data[
i] = modeM*(phase_carrier_at_f_max + der_phase_carrier_at_f_max*(freq_mode_lm->data[
i]/modeM-f_max_carrier)) + const_phase_shift;
1154 gsl_spline_free(spline);
1155 gsl_interp_accel_free(acc);
1164 gsl_vector* real_f_lo = gsl_vector_alloc(freq_lo->size);
1165 gsl_vector* imag_f_lo = gsl_vector_alloc(freq_lo->size);
1166 gsl_vector* real_f_hi = gsl_vector_alloc(freq_hi->size);
1167 gsl_vector* imag_f_hi = gsl_vector_alloc(freq_hi->size);
1180 gsl_vector_free(real_f_lo);
1181 gsl_vector_free(imag_f_lo);
1182 gsl_vector_free(real_f_hi);
1183 gsl_vector_free(imag_f_hi);
1199 "Error setting up SEOBNRv4ROM data - check your $LAL_DATA_PATH\n");
1202 UNUSED
UINT4 retcode=0;
1205 SEOBNRROMdataDS_submodel *submodel_hi;
1206 SEOBNRROMdataDS_submodel *submodel_lo;
1210 submodel_lo = romdata->lowf;
1213 if(flag_patch == 0){
1214 submodel_hi = romdata->hqls;
1216 else if(flag_patch == 1){
1217 submodel_hi = romdata->hqhs;
1219 else if(flag_patch == 2){
1220 submodel_hi = romdata->lqls;
1222 else if(flag_patch == 3){
1223 submodel_hi = romdata->lqhs;
1227 XLALPrintError(
"XLAL Error - %s: SEOBNRv4HM not currently available in this region!\n",
1237 gsl_vector* freq_lo = gsl_vector_alloc(submodel_lo->nk_cmode);
1238 gsl_vector* freq_hi = gsl_vector_alloc(submodel_hi->nk_cmode);
1240 for(
unsigned int i = 0;
i < freq_lo->size;
i++){
1241 freq_lo->data[
i] = submodel_lo->gCMode->data[
i];
1248 for(
unsigned int i = 0;
i < freq_hi->size;
i++){
1249 freq_hi->data[
i] = inv_scaling*submodel_hi->gCMode->data[
i];
1256 *freq_cmode = gsl_vector_alloc(i_max_LF + freq_hi->size - i_min_HF + 1);
1259 for(
unsigned int i = 0;
i <= i_max_LF;
i++){
1260 (*freq_cmode)->data[
i] = freq_lo->data[
i];
1262 for(
unsigned int i = i_min_HF;
i < freq_hi->size;
i++){
1263 (*freq_cmode)->data[i_max_LF+
i-i_min_HF+1] = freq_hi->data[
i];
1266 *cmode_real = gsl_vector_calloc((*freq_cmode)->size);
1267 *cmode_imag = gsl_vector_calloc((*freq_cmode)->size);
1276 gsl_vector_free(freq_lo);
1277 gsl_vector_free(freq_hi);
1291 "Error setting up SEOBNRv4ROM data - check your $LAL_DATA_PATH\n");
1294 SEOBNRROMdataDS_submodel *submodel;
1295 if(strcmp(
"LF",freq_range) == 0){
1297 submodel = romdata->lowf;
1303 if(flag_patch == 0){
1304 submodel = romdata->hqls;
1306 else if(flag_patch == 1){
1307 submodel = romdata->hqhs;
1309 else if(flag_patch == 2){
1310 submodel = romdata->lqls;
1312 else if(flag_patch == 3){
1313 submodel = romdata->lqhs;
1317 XLALPrintError(
"XLAL Error - %s: SEOBNRv4HM not currently available in this region!\n",
1330 submodel->cvec_phase,
1336 gsl_vector_const_ptr(submodel->qvec, 0),
1337 gsl_vector_const_ptr(submodel->chi1vec, 0),
1338 gsl_vector_const_ptr(submodel->chi2vec, 0),
1349 gsl_blas_dgemv(CblasTrans, 1.0, submodel->Bphase, romdata_coeff->
c_phase, 0.0, phase_f);
1364 "Error setting up SEOBNRv4ROM data - check your $LAL_DATA_PATH\n");
1367 SEOBNRROMdataDS_submodel *submodel;
1368 if(strcmp(
"LF",freq_range) == 0){
1370 submodel = romdata->lowf;
1376 if(flag_patch == 0){
1377 submodel = romdata->hqls;
1379 else if(flag_patch == 1){
1380 submodel = romdata->hqhs;
1382 else if(flag_patch == 2){
1383 submodel = romdata->lqls;
1385 else if(flag_patch == 3){
1386 submodel = romdata->lqhs;
1390 XLALPrintError(
"XLAL Error - %s: SEOBNRv4HM not currently available in this region!\n",
1403 submodel->cvec_real,
1409 gsl_vector_const_ptr(submodel->qvec, 0),
1410 gsl_vector_const_ptr(submodel->chi1vec, 0),
1411 gsl_vector_const_ptr(submodel->chi2vec, 0),
1420 submodel->cvec_imag,
1426 gsl_vector_const_ptr(submodel->qvec, 0),
1427 gsl_vector_const_ptr(submodel->chi1vec, 0),
1428 gsl_vector_const_ptr(submodel->chi2vec, 0),
1440 gsl_blas_dgemv(CblasTrans, 1.0, submodel->Breal, romdata_coeff->
c_real, 0.0, creal_f);
1441 gsl_blas_dgemv(CblasTrans, 1.0, submodel->Bimag, romdata_coeff->
c_imag, 0.0, cimag_f);
1452 if ((
q> 3.) && (chi1<=0.8)){
1455 else if ((
q> 3.) && (chi1>0.8)){
1458 else if ((
q<= 3.) && (chi1<=0.8)){
1461 else if ((
q<= 3.) && (chi1>0.8)){
1466 XLALPrintError(
"XLAL Error - %s: SEOBNRv4HM not currently available in this region!\n",
1483 if(!ampPhaseSplineData)
1488 if (
q > 50.0)
nudge(&
q, 50.0, 1
e-6);
1490 if ( chi1 < -1.0 || chi2 < -1.0 || chi1 > 1.0 || chi2 > 1.0) {
1491 XLALPrintError(
"XLAL Error - %s: chi1 or chi2 smaller than -1.0 or larger than 1.0!\n"
1492 "SEOBNRv4HMROM is only available for spins in the range -1 <= a/M <= 1.0.\n",
1497 if (q<1.0 || q > 50.0) {
1498 XLALPrintError(
"XLAL Error - %s: q (%f) bigger than 50.0 or unphysical!\n"
1499 "SEOBNRv4HMROM is only available for q in the range 1 <= q <= 50.\n",
1508 gsl_vector *freq_carrier_hyb = NULL;
1509 gsl_vector *phase_carrier_hyb = NULL;
1514 &freq_carrier_hyb, &phase_carrier_hyb,
q, chi1, chi2, flag_patch, nk_max);
1518 for(
unsigned int i=0;
i < phase_carrier_hyb->size;
i++) {
1519 phase_carrier_hyb->data[
i] = -phase_carrier_hyb->data[
i];
1523 for(
unsigned int nMode=0; nMode <
nModes; nMode++){
1525 gsl_vector *freq_cmode_hyb = NULL;
1526 gsl_vector *cmode_real_hyb = NULL;
1527 gsl_vector *cmode_imag_hyb = NULL;
1534 &freq_cmode_hyb, &cmode_real_hyb, &cmode_imag_hyb,
1535 q, chi1, chi2, nMode, flag_patch, nk_max);
1537 gsl_vector *phase_approx_lm = gsl_vector_alloc(freq_cmode_hyb->size);
1540 freq_carrier_hyb, phase_carrier_hyb, nMode);
1544 gsl_vector *phase_cmode = gsl_vector_alloc(freq_cmode_hyb->size);
1545 for(
unsigned int i=0;
i < freq_cmode_hyb->size;
i++) {
1546 complex_mode = cmode_real_hyb->data[
i] + I*cmode_imag_hyb->data[
i];
1547 phase_cmode->data[
i] = carg(complex_mode);
1551 gsl_vector *unwrapped_phase_cmode = gsl_vector_alloc(freq_cmode_hyb->size);
1552 retcode =
unwrap_phase(unwrapped_phase_cmode,phase_cmode);
1555 gsl_vector *reconstructed_phase = gsl_vector_alloc(freq_cmode_hyb->size);
1556 gsl_vector *reconstructed_amplitude = gsl_vector_alloc(freq_cmode_hyb->size);
1557 for(
unsigned int i=0;
i < freq_cmode_hyb->size;
i++) {
1558 complex_mode = cmode_real_hyb->data[
i] + I*cmode_imag_hyb->data[
i];
1559 reconstructed_amplitude->data[
i] = cabs(complex_mode);
1560 reconstructed_phase->data[
i] = unwrapped_phase_cmode->data[
i] - phase_approx_lm->data[
i];
1564 gsl_interp_accel *acc_amp = gsl_interp_accel_alloc();
1565 gsl_spline *spline_amp = gsl_spline_alloc (gsl_interp_cspline, reconstructed_amplitude->size);
1566 gsl_spline_init(spline_amp, freq_cmode_hyb->data, reconstructed_amplitude->data, reconstructed_amplitude->size);
1568 gsl_interp_accel *acc_phase = gsl_interp_accel_alloc();
1569 gsl_spline *spline_phase = gsl_spline_alloc (gsl_interp_cspline, reconstructed_phase->size);
1570 gsl_spline_init(spline_phase, freq_cmode_hyb->data, reconstructed_phase->data, reconstructed_phase->size);
1574 ampPhaseSplineData[nMode]->spline_amp = spline_amp;
1575 ampPhaseSplineData[nMode]->spline_phi = spline_phase;
1576 ampPhaseSplineData[nMode]->acc_amp = acc_amp;
1577 ampPhaseSplineData[nMode]->acc_phi = acc_phase;
1578 ampPhaseSplineData[nMode]->f = freq_cmode_hyb;
1581 gsl_vector_free(cmode_real_hyb);
1582 gsl_vector_free(cmode_imag_hyb);
1583 gsl_vector_free(phase_approx_lm);
1584 gsl_vector_free(phase_cmode);
1585 gsl_vector_free(unwrapped_phase_cmode);
1586 gsl_vector_free(reconstructed_amplitude);
1587 gsl_vector_free(reconstructed_phase);
1591 gsl_vector_free(freq_carrier_hyb);
1592 gsl_vector_free(phase_carrier_hyb);
1605 UNUSED
REAL8 phiRef,
1607 UNUSED
REAL8 distance,
1608 UNUSED
REAL8 Mtot_sec,
1613 UNUSED
REAL8 deltaF,
1617 REAL8 sign_odd_modes
1626 if (
q > 50.0)
nudge(&
q, 50.0, 1
e-6);
1628 if ( chi1 < -1.0 || chi2 < -1.0 || chi1 > 1.0 || chi2 > 1.0) {
1629 XLALPrintError(
"XLAL Error - %s: chi1 or chi2 smaller than -1.0 or larger than 1.0!\n"
1630 "SEOBNRv4HMROM is only available for spins in the range -1 <= a/M <= 1.0.\n",
1635 if (q<1.0 || q > 50.0) {
1636 XLALPrintError(
"XLAL Error - %s: q (%f) bigger than 50.0 or unphysical!\n"
1637 "SEOBNRv4HMROM is only available for q in the range 1 <= q <= 50.\n",
1647 ampPhaseSplineData,
q, chi1, chi2, nk_max,
nModes);
1653 REAL8 fLow = freqs_in->data[0];
1654 REAL8 fHigh = freqs_in->data[freqs_in->length - 1];
1656 UNUSED
REAL8 fLow_geom = fLow * Mtot_sec;
1657 REAL8 fHigh_geom = fHigh * Mtot_sec;
1658 REAL8 deltaF_geom = deltaF * Mtot_sec;
1663 if (fHigh_geom == 0)
1669 if (fHigh_geom <= fLow_geom)
1670 XLAL_ERROR(
XLAL_EDOM,
"End frequency %g is smaller than (or equal to) starting frequency %g!\n", fHigh_geom, fLow_geom);
1673 for(
unsigned int nMode=0; nMode <
nModes; nMode++){
1684 npts =
NextPow2(fHigh_geom / deltaF_geom) + 1;
1685 if (fHigh_geom < fHigh * Mtot_sec)
1686 npts =
NextPow2(fHigh * Mtot_sec / deltaF_geom) + 1;
1694 double fHigh_temp = fHigh_geom / Mtot_sec;
1696 UINT4 iStop = (
UINT4) ceil(fHigh_temp / deltaF);
1700 freqs->
data[
i-iStart] =
i*deltaF_geom;
1719 REAL8 t_corr = 1000.;
1722 gsl_spline *spline_amp = ampPhaseSplineData[nMode]->
spline_amp;
1723 gsl_spline *spline_phase = ampPhaseSplineData[nMode]->
spline_phi;
1724 gsl_interp_accel *acc_amp = ampPhaseSplineData[nMode]->
acc_amp;
1725 gsl_interp_accel *acc_phase = ampPhaseSplineData[nMode]->
acc_phi;
1734 if (f > Mf_max_mode)
continue;
1735 if (f <=
Mf_low_22 * modeM/2.)
continue;
1737 REAL8 A = gsl_spline_eval(spline_amp, f, acc_amp);
1738 REAL8 phase = gsl_spline_eval(spline_phase, f, acc_phase);
1739 hlmdata[j] = amp0*A * (cos(phase) + I*sin(phase));
1741 COMPLEX16 t_factor = cos(phase_factor) + I*sin(phase_factor);
1742 hlmdata[j] *= t_factor;
1745 hlmdata[j] = pow(-1.,modeL)*conj(hlmdata[j]);
1749 hlmdata[j] = hlmdata[j]*sign_odd_modes;
1813 for (
INT4 EMM = -ELL; EMM <= (
INT4)ELL; EMM++) {
1820 if ((modeL == ELL)&&(modeM == EMM)) {
1823 if ((modeL == ELL)&&(modeM == -EMM)) {
1829 if (flagTrue == 0) {
1830 XLALPrintError (
"Mode (%d,%d) is not available by the model SEOBNRv4HM_ROM\n", ELL,
1834 if (flagTrue == 2) {
1835 XLALPrintError (
"Mode (%d,%d) is not available by the model SEOBNRv4HM_ROM.\n"
1836 "In this function you can only select (l,-|m|) modes that are directly modeled in the ROM.\n"
1837 "The (l,+|m|) mode will be automatically added to the waveform using symmetry arguments.\n", ELL,
1859 LALValue *ModeArray,
1867 while ( hlms_temp ) {
1871 hlms_temp->
l, hlms_temp->
m, 1);
1873 hlms_temp = hlms_temp->
next;
1884 if (
l==2 &&
m==2)
return 0.;
1885 else if (
l==2 &&
m==1)
return LAL_PI/2;
1886 else if (
l==3 &&
m==3)
return -
LAL_PI/2;
1887 else if (
l==4 &&
m==4)
return LAL_PI;
1888 else if (
l==5 &&
m==5)
return LAL_PI/2;
1902 double chis = 1./2 * (chi1 + chi2);
1903 double chia = 1./2 * (chi1 - chi2);
1904 if (
l==2 &&
m==2)
return 1.;
1905 else if (
l==2 &&
m==1)
return v * (
delta/3 - 1./2*v*(chia +
delta*chis));
1906 else if (
l==3 &&
m==3)
return v * 3./4 * sqrt(15./14) *
delta;
1907 else if (
l==4 &&
m==4)
return v*v * 8*sqrt(35.)/63 * (1 - 3*eta);
1908 else if (
l==5 &&
m==5)
return v*v*v * 625*sqrt(66.)/6336 *
delta * (1 - 2*eta);
1929 gsl_vector **PNphase
1933 *PNphase = gsl_vector_alloc(Mfs->size);
1940 double m1OverM =
q / (1.0+
q);
1941 double m2OverM = 1.0 / (1.0+
q);
1951 for (
size_t i=0;
i < Mfs->size;
i++) {
1952 const double Mf = gsl_vector_get(Mfs,
i);
1953 const double Mf_m = 2./
m * Mf;
1954 const double v = cbrt(
LAL_PI * Mf_m);
1955 const double logv = log(v);
1956 const double v2 = v * v;
1957 const double v3 = v * v2;
1958 const double v4 = v * v3;
1959 const double v5 = v * v4;
1960 const double v6 = v * v5;
1961 const double v7 = v * v6;
1962 double phasing = 0.0;
1964 phasing +=
pn->v[7] * v7;
1965 phasing += (
pn->v[6] +
pn->vlogv[6] * logv) * v6;
1966 phasing += (
pn->v[5] +
pn->vlogv[5] * logv) * v5;
1967 phasing +=
pn->v[4] * v4;
1968 phasing +=
pn->v[3] * v3;
1969 phasing +=
pn->v[2] * v2;
1970 phasing +=
pn->v[1] * v;
1971 phasing +=
pn->v[0];
1980 phasing += Deltaphilm -
LAL_PI/4.;
1982 gsl_vector_set(*PNphase,
i, phasing);
2009 *PNamp = gsl_vector_alloc(Mfs->size);
2010 double eta =
q / ((1.+
q)*(1.+
q));
2014 double delta = (
q-1. + DBL_EPSILON) / (1.+
q);
2017 double ampN =
LAL_PI * sqrt(2*eta/3.);
2020 for (
size_t i=0;
i < Mfs->size;
i++) {
2021 const double Mf = gsl_vector_get(Mfs,
i);
2022 const double Mf_m = 2./
m * Mf;
2023 const double v = cbrt(
LAL_PI * Mf_m);
2024 const double vm72 = pow(v, -7./2);
2028 double amp = ampN * vm72 * sqrt(2./
m) * mode_amp_factor;
2029 gsl_vector_set(*PNamp,
i, amp);
2048 if (!(Mfmin < Mfmax))
2051 double eta =
q / ((1.+
q) * (1.+
q));
2056 double Lambda = 3.8 * pow(acc * eta, 1./4) * pow(
LAL_PI, 5./12);
2060 double Lambdatilde = 0.;
2061 N = 1 + ceil(12./5/
Lambda * (pow(Mfmin, -5./12) - pow(Mfmax, -5./12)));
2063 Lambdatilde = 12./5/(
N-1) * (pow(Mfmin, -5./12) - pow(Mfmax, -5./12));
2066 *Mfreq = gsl_vector_alloc(
N);
2069 double Mfmin_m512 = pow(Mfmin, -5./12);
2070 for (
int i=0;
i<
N;
i++) {
2071 (*Mfreq)->data[
i] = pow(Mfmin_m512 - 5./12*Lambdatilde*
i, -12./5);
2075 (*Mfreq)->data[0] = Mfmin;
2076 (*Mfreq)->data[
N-1] = Mfmax;
2082 gsl_spline **hyb_spline,
2084 gsl_vector *PN_freq,
2086 double f_hyb_win_lo,
2090 gsl_vector *ROM_amp_f = NULL;
2091 gsl_vector *ROM_amp = NULL;
2095 if ( (gsl_vector_get(PN_freq, 0) > f_hyb_win_lo)
2096 || (gsl_vector_get(PN_freq, PN_freq->size - 1) < f_hyb_win_lo)
2097 || (gsl_vector_get(PN_freq, 0) > f_hyb_win_hi)
2098 || (gsl_vector_get(PN_freq, PN_freq->size - 1) < f_hyb_win_hi) )
2099 XLAL_ERROR(
XLAL_EFUNC,
"Hybridization window for amplitude is not contained in PN frequencies.");
2100 if ( (gsl_vector_get(ROM_amp_f, 0) > f_hyb_win_lo)
2101 || (gsl_vector_get(ROM_amp_f, ROM_amp_f->size - 1) < f_hyb_win_lo)
2102 || (gsl_vector_get(ROM_amp_f, 0) > f_hyb_win_hi)
2103 || (gsl_vector_get(ROM_amp_f, ROM_amp_f->size - 1) < f_hyb_win_hi) )
2104 XLAL_ERROR(
XLAL_EFUNC,
"Hybridization window for amplitude is not contained in ROM frequencies.");
2107 gsl_spline *PN_amp_spline = gsl_spline_alloc(gsl_interp_cspline, PN_amp->size);
2108 gsl_spline_init(PN_amp_spline, PN_freq->data, PN_amp->data, PN_amp->size);
2109 gsl_interp_accel *acc_PN = gsl_interp_accel_alloc();
2110 gsl_interp_accel *acc_ROM = gsl_interp_accel_alloc();
2111 double PN_amp_i = gsl_spline_eval(PN_amp_spline, f_hyb_win_lo, acc_PN);
2112 double ROM_amp_i = gsl_spline_eval(ampPhaseSplineData_for_mode->
spline_amp, f_hyb_win_lo, acc_ROM);
2113 double fac = ROM_amp_i / PN_amp_i;
2114 for (
size_t i=0;
i < PN_amp->size;
i++) {
2115 double A = gsl_vector_get(PN_amp,
i);
2116 gsl_vector_set(PN_amp,
i, A * fac);
2118 gsl_spline_free(PN_amp_spline);
2119 gsl_interp_accel_free(acc_PN);
2120 gsl_interp_accel_free(acc_ROM);
2122 gsl_vector *hyb_freq = NULL;
2123 gsl_vector *hyb_amp = NULL;
2125 &hyb_freq, &hyb_amp,
2128 f_hyb_win_lo, f_hyb_win_hi
2131 *hyb_spline = gsl_spline_alloc(gsl_interp_cspline, hyb_amp->size);
2132 gsl_spline_init(*hyb_spline, hyb_freq->data, hyb_amp->data, hyb_amp->size);
2134 gsl_vector_free(ROM_amp_f);
2135 gsl_vector_free(ROM_amp);
2136 gsl_vector_free(hyb_freq);
2137 gsl_vector_free(hyb_amp);
2143 gsl_spline **hyb_spline,
2144 REAL8* Deltat_align,
2145 REAL8* Deltaphi_align,
2147 gsl_vector *PN_freq,
2148 gsl_vector *PN_phase,
2149 double f_hyb_win_lo,
2153 gsl_vector *ROM_phi_f = NULL;
2154 gsl_vector *ROM_phi = NULL;
2158 if ( (gsl_vector_get(PN_freq, 0) > f_hyb_win_lo)
2159 || (gsl_vector_get(PN_freq, PN_freq->size - 1) < f_hyb_win_lo)
2160 || (gsl_vector_get(PN_freq, 0) > f_hyb_win_hi)
2161 || (gsl_vector_get(PN_freq, PN_freq->size - 1) < f_hyb_win_hi) )
2163 if ( (gsl_vector_get(ROM_phi_f, 0) > f_hyb_win_lo)
2164 || (gsl_vector_get(ROM_phi_f, ROM_phi_f->size - 1) < f_hyb_win_lo)
2165 || (gsl_vector_get(ROM_phi_f, 0) > f_hyb_win_hi)
2166 || (gsl_vector_get(ROM_phi_f, ROM_phi_f->size - 1) < f_hyb_win_hi) )
2169 gsl_vector *hyb_freq = NULL;
2170 gsl_vector *hyb_phase = NULL;
2172 &hyb_freq, &hyb_phase, Deltat_align, Deltaphi_align,
2175 f_hyb_win_lo, f_hyb_win_hi
2179 *hyb_spline = gsl_spline_alloc(gsl_interp_cspline, hyb_phase->size);
2180 gsl_spline_init(*hyb_spline, hyb_freq->data, hyb_phase->data, hyb_phase->size);
2182 gsl_vector_free(ROM_phi_f);
2183 gsl_vector_free(ROM_phi);
2184 gsl_vector_free(hyb_freq);
2185 gsl_vector_free(hyb_phase);
2191 gsl_spline **hyb_spline,
2193 gsl_vector *PN_freq,
2194 gsl_vector *PN_phase,
2195 double f_hyb_win_lo,
2196 double f_hyb_win_hi,
2197 REAL8 Deltat_22_align,
2198 REAL8 Deltaphi_22_align,
2202 gsl_vector *ROM_phi_f = NULL;
2203 gsl_vector *ROM_phi = NULL;
2207 if ( (gsl_vector_get(PN_freq, 0) > f_hyb_win_lo)
2208 || (gsl_vector_get(PN_freq, PN_freq->size - 1) < f_hyb_win_lo)
2209 || (gsl_vector_get(PN_freq, 0) > f_hyb_win_hi)
2210 || (gsl_vector_get(PN_freq, PN_freq->size - 1) < f_hyb_win_hi) )
2212 if ( (gsl_vector_get(ROM_phi_f, 0) > f_hyb_win_lo)
2213 || (gsl_vector_get(ROM_phi_f, ROM_phi_f->size - 1) < f_hyb_win_lo)
2214 || (gsl_vector_get(ROM_phi_f, 0) > f_hyb_win_hi)
2215 || (gsl_vector_get(ROM_phi_f, ROM_phi_f->size - 1) < f_hyb_win_hi) )
2218 gsl_vector *hyb_freq = NULL;
2219 gsl_vector *hyb_phase = NULL;
2221 &hyb_freq, &hyb_phase,
2224 f_hyb_win_lo, f_hyb_win_hi,
2225 Deltat_22_align, Deltaphi_22_align, modeM
2229 *hyb_spline = gsl_spline_alloc(gsl_interp_cspline, hyb_phase->size);
2230 gsl_spline_init(*hyb_spline, hyb_freq->data, hyb_phase->data, hyb_phase->size);
2232 gsl_vector_free(ROM_phi_f);
2233 gsl_vector_free(ROM_phi);
2234 gsl_vector_free(hyb_freq);
2235 gsl_vector_free(hyb_phase);
2245 UNUSED
REAL8 phiRef,
2247 UNUSED
REAL8 distance,
2248 UNUSED
REAL8 Mtot_sec,
2253 UNUSED
REAL8 deltaF,
2260 REAL8 sign_odd_modes
2265 REAL8 fLow = freqs_in->data[0];
2266 REAL8 fHigh = freqs_in->data[freqs_in->length - 1];
2268 REAL8 fLow_geom = fLow * Mtot_sec;
2269 REAL8 fHigh_geom = fHigh * Mtot_sec;
2270 REAL8 deltaF_geom = deltaF * Mtot_sec;
2275 if (fHigh_geom == 0)
2282 XLAL_PRINT_INFO(
"Starting frequency %g is smaller than (or equal to) ROM starting frequency for (2,2) mode %g!\nUsing hybridization with TaylorF2.\n", fLow_geom,
Mf_low_22);
2284 XLAL_PRINT_INFO(
"Starting frequency %g is smaller than (or equal to) ROM starting frequency for (5,5) mode %g!\nUsing hybridization with TaylorF2.\n", fLow_geom,
Mf_low_55);
2285 if (fLow_geom <= 0.0) {
2286 XLALPrintError(
"XLAL Error - %s: Starting frequency in REAL8Sequence must be positive.\n", __func__);
2293 ampPhaseSplineData,
q, chi1, chi2, nk_max,
nModes);
2298 const double f_hyb_win_lo_fac = 1.01;
2299 const double f_hyb_win_hi_fac = 2.0;
2308 double PN_Mf_low = fmin(fLow_geom / 2.0,
Mf_low_21);
2309 double PN_Mf_high = 1.1 * f_hyb_win_hi_fac *
Mf_low_55;
2311 gsl_vector *Mfs = NULL;
2312 const double acc = 1
e-4;
2317 gsl_spline *hybrid_spline_amp[
nModes];
2318 gsl_spline *hybrid_spline_phi[
nModes];
2320 hybrid_spline_amp[
i] = NULL;
2321 hybrid_spline_phi[
i] = NULL;
2326 REAL8 Deltat_22_align = 0.;
2327 REAL8 Deltaphi_22_align = 0.;
2332 double f_hyb_win_lo =
Mf_low_lm[k] * f_hyb_win_lo_fac;
2333 double f_hyb_win_hi =
Mf_low_lm[k] * f_hyb_win_hi_fac;
2335 XLALPrintInfo(
"%s : SEOBNRv4HM_ROM hybridization window for (2,2) mode: Mf in [%g, %g]\n",
2336 __func__, f_hyb_win_lo, f_hyb_win_hi);
2340 gsl_vector *PNamp = NULL;
2341 gsl_vector *PNphase = NULL;
2345 retcode |=
TaylorF2Phasing(Mtot,
q, chi1, chi2, modeL, modeM, Mfs, &PNphase);
2347 gsl_vector_free(PNamp);
2348 gsl_vector_free(PNphase);
2349 gsl_vector_free(Mfs);
2358 if (!(modeL==2 && modeM==2)) {
2364 &hybrid_spline_phi[k],
2367 ampPhaseSplineData[k],
2369 f_hyb_win_lo, f_hyb_win_hi
2375 &hybrid_spline_phi[k],
2376 ampPhaseSplineData[k],
2378 f_hyb_win_lo, f_hyb_win_hi,
2379 Deltat_22_align, Deltaphi_22_align, modeM
2385 &hybrid_spline_amp[k],
2386 ampPhaseSplineData[k],
2388 f_hyb_win_lo, f_hyb_win_hi
2392 gsl_interp_accel *acc_amp = gsl_interp_accel_alloc();
2393 gsl_interp_accel *acc_phase = gsl_interp_accel_alloc();
2405 npts =
NextPow2(fHigh_geom / deltaF_geom) + 1;
2406 if (fHigh_geom < fHigh * Mtot_sec)
2407 npts =
NextPow2(fHigh * Mtot_sec / deltaF_geom) + 1;
2412 "hlmtilde: FD mode", &tC, 0.0, deltaF, &
lalStrainUnit, npts);
2416 double fHigh_temp = fHigh_geom / Mtot_sec;
2418 UINT4 iStop = (
UINT4) ceil(fHigh_temp / deltaF);
2422 freqs->
data[
i-iStart] =
i*deltaF_geom;
2427 npts = freqs_in->length;
2431 "hlmtilde: FD mode", &tC, fLow, deltaF, &
lalStrainUnit, npts);
2435 for (
UINT4 i=0;
i<freqs_in->length;
i++)
2436 freqs->
data[
i] = freqs_in->data[
i] * Mtot_sec;
2445 double amp0 = Mtot * Mtot_sec *
LAL_MRSUN_SI / (distance);
2449 double t_corr = 1000.0;
2453 q, chi1, chi2, modeL, modeM) / (2.0*
LAL_PI);
2457 double f = freqs->
data[
i];
2458 if (f > Mf_max_mode)
continue;
2462 REAL8 A = gsl_spline_eval(hybrid_spline_amp[k], f, acc_amp);
2463 REAL8 phase = gsl_spline_eval(hybrid_spline_phi[k], f, acc_phase);
2464 hlmdata[j] = amp0*A * (cos(phase) + I*sin(phase));
2466 COMPLEX16 t_factor = cos(phase_factor) + I*sin(phase_factor);
2467 hlmdata[j] *= t_factor;
2470 hlmdata[j] = pow(-1.0, modeL) * conj(hlmdata[j]);
2474 hlmdata[j] = hlmdata[j] * sign_odd_modes;
2482 gsl_interp_accel_free(acc_amp);
2483 gsl_interp_accel_free(acc_phase);
2484 gsl_vector_free(PNamp);
2485 gsl_vector_free(PNphase);
2490 gsl_vector_free(Mfs);
2494 gsl_spline_free(hybrid_spline_amp[k]);
2495 gsl_spline_free(hybrid_spline_phi[k]);
2540 UNUSED
struct tagCOMPLEX16FrequencySeries **hptilde,
2541 UNUSED
struct tagCOMPLEX16FrequencySeries **hctilde,
2542 UNUSED
REAL8 phiRef,
2543 UNUSED
REAL8 deltaF,
2547 UNUSED
REAL8 distance,
2548 UNUSED
REAL8 inclination,
2555 bool use_hybridization,
2559 REAL8 sign_odd_modes = 1.;
2563 REAL8 m1temp = m1SI;
2564 REAL8 chi1temp = chi1;
2569 sign_odd_modes = -1.;
2575 REAL8 Mtot = mass1+mass2;
2582 if (ModeArray == NULL) {
2597 freqs->
data[0] = fLow;
2598 freqs->
data[1] = fHigh;
2601#ifdef LAL_PTHREAD_LOCK
2610 if (use_hybridization) {
2612 phiRef, fRef, distance, Mtot_sec,
q, chi1, chi2, freqs, deltaF, nk_max,
2617 phiRef, fRef, distance, Mtot_sec,
q, chi1, chi2, freqs, deltaF, nk_max,
2631 memset(hPlustilde->data->data, 0, npts *
sizeof(
COMPLEX16));
2632 memset(hCrosstilde->data->data, 0, npts *
sizeof(
COMPLEX16));
2639 (*hptilde) = hPlustilde;
2640 (*hctilde) = hCrosstilde;
2647 const char*
s = getenv(
"FREE_MEMORY_SEOBNRv4HMROM");
2649 for(
unsigned int index_mode = 0; index_mode <
nModes;index_mode++){
2665 UNUSED
struct tagCOMPLEX16FrequencySeries **hptilde,
2666 UNUSED
struct tagCOMPLEX16FrequencySeries **hctilde,
2668 UNUSED
REAL8 phiRef,
2670 UNUSED
REAL8 distance,
2671 UNUSED
REAL8 inclination,
2681 REAL8 sign_odd_modes = 1.;
2685 REAL8 m1temp = m1SI;
2686 REAL8 chi1temp = chi1;
2691 sign_odd_modes = -1.;
2697 REAL8 Mtot = mass1+mass2;
2704 if (ModeArray == NULL) {
2716#ifdef LAL_PTHREAD_LOCK
2726 double deltaF = 0.0;
2731 phiRef, fRef, distance, Mtot_sec,
q, chi1, chi2, freqs, deltaF, nk_max,
2741 double fLow = freqs->
data[0];
2744 "hptilde: FD waveform", &tGPS, fLow, deltaF, &
lalStrainUnit, npts);
2746 "hctilde: FD waveform", &tGPS, fLow, deltaF, &
lalStrainUnit, npts);
2747 memset(hPlustilde->data->data, 0, npts *
sizeof(
COMPLEX16));
2748 memset(hCrosstilde->data->data, 0, npts *
sizeof(
COMPLEX16));
2755 (*hptilde) = hPlustilde;
2756 (*hctilde) = hCrosstilde;
2762 const char*
s = getenv(
"FREE_MEMORY_SEOBNRv4HMROM");
2764 for(
unsigned int index_mode = 0; index_mode <
nModes;index_mode++){
2781 UNUSED
REAL8 phiRef,
2782 UNUSED
REAL8 deltaF,
2793 bool use_hybridization
2796 REAL8 sign_odd_modes = 1.;
2800 REAL8 m1temp = m1SI;
2801 REAL8 chi1temp = chi1;
2806 sign_odd_modes = -1.;
2811 XLAL_PRINT_ERROR(
"Requested number of modes not available. Set nModes = 0 to get all the available modes.\n");
2818 REAL8 Mtot = mass1+mass2;
2829 freqs->
data[0] = fLow;
2830 freqs->
data[1] = fHigh;
2833#ifdef LAL_PTHREAD_LOCK
2840 UNUSED
UINT8 retcode;
2842 if (use_hybridization) {
2845 Mtot_sec,
q, chi1, chi2, freqs,
2846 deltaF, nk_max, 5, sign_odd_modes);
2849 Mtot_sec,
q, chi1, chi2, freqs,
2850 deltaF, nk_max,
nModes, sign_odd_modes);
2855 Mtot_sec,
q, chi1, chi2, freqs,
2856 deltaF, nk_max, 5, sign_odd_modes);
2859 Mtot_sec,
q, chi1, chi2, freqs,
2860 deltaF, nk_max,
nModes, sign_odd_modes);
2877 UNUSED
REAL8 phiRef,
2879 UNUSED
REAL8 distance,
2880 UNUSED
REAL8 inclination,
2890 REAL8 sign_odd_modes = 1.;
2894 REAL8 m1temp = m1SI;
2895 REAL8 chi1temp = chi1;
2900 sign_odd_modes = -1.;
2906 REAL8 Mtot = mass1+mass2;
2913 if (ModeArray == NULL) {
2925#ifdef LAL_PTHREAD_LOCK
2934 double deltaF = 0.0;
2939 phiRef, fRef, distance, Mtot_sec,
q, chi1, chi2, freqs, deltaF, nk_max,
2946 const char*
s = getenv(
"FREE_MEMORY_SEOBNRv4HMROM");
2948 for(
unsigned int index_mode = 0; index_mode <
nModes;index_mode++){
struct tagLALH5File LALH5File
void XLALDestroyDict(LALDict *dict)
LALDict * XLALCreateDict(void)
Auxiliary functions related to HDF5 waveform data files.
static const REAL8 Mf_ROM_max
static void nudge(REAL8 *x, REAL8 X, REAL8 epsilon)
static double double delta
Auxiliary functions for SEOBNRv1/v2 reduced order modeling codes in LALSimIMRSEOBNRv2ROMDoubleSpin....
static UNUSED UINT4 align_wfs_window_from_22(gsl_vector *f_array_1, gsl_vector *f_array_2, gsl_vector *phase_1, gsl_vector *phase_2, REAL8 f_align_start, REAL8 f_align_end, REAL8 Deltat22, REAL8 Deltaphi22, INT4 modeM)
static UNUSED UINT4 compute_i_max_LF_i_min_HF(INT8 *i_max_LF, INT8 *i_min_LF, gsl_vector *freqs_in_1, gsl_vector *freqs_in_2, REAL8 freq_1)
static UNUSED REAL8 Interpolate_Coefficent_Tensor(gsl_vector *v, REAL8 eta, REAL8 chi1, REAL8 chi2, int ncy, int ncz, gsl_bspline_workspace *bwx, gsl_bspline_workspace *bwy, gsl_bspline_workspace *bwz)
static UNUSED REAL8 Get_omegaQNM_SEOBNRv4(REAL8 q, REAL8 chi1z, REAL8 chi2z, UINT4 l, UINT4 m)
static UNUSED UINT4 unwrap_phase(gsl_vector *phaseout, gsl_vector *phasein)
static UNUSED UINT4 align_wfs_window(gsl_vector *f_array_1, gsl_vector *f_array_2, gsl_vector *phase_1, gsl_vector *phase_2, REAL8 *Deltat, REAL8 *Deltaphi, REAL8 f_align_start, REAL8 f_align_end)
static UNUSED char * concatenate_strings(int count,...)
static UNUSED UINT4 blend_functions(gsl_vector *freqs_out, gsl_vector *out_fun, gsl_vector *freq_in_1, gsl_vector *fun_in_1, gsl_vector *freq_in_2, gsl_vector *fun_in_2, REAL8 freq_1, REAL8 freq_2)
static UNUSED UINT8 SEOBNRv4HMROM_Select_HF_patch(REAL8 q, REAL8 chi1)
static UNUSED void AmpPhaseSplineData_Destroy(AmpPhaseSplineData **data, const int num_modes)
static UNUSED bool SEOBNRv4HMROM_IsSetup(UINT4)
Helper function to check if the SEOBNRv4HMROM model has been initialised.
static SEOBNRROMdataDS __lalsim_SEOBNRv4HMROMDS_data[NMODES]
static UNUSED UINT8 SEOBNRv4HMROM_freq_cmode_sparse_grid_hybrid(gsl_vector **freq_cmode, gsl_vector **cmode_real, gsl_vector **cmode_imag, REAL8 q, REAL8 chi1, REAL8 chi2, UINT8 nMode, UINT8 flag_patch, INT8 nk_max)
static INT8 Check_EOBROM_mode_array_structure(LALValue *ModeArray, UINT4 nModes)
ModeArray is a structure which allows to select the modes to include in the waveform.
static UNUSED int SEOBNRv4HMROM_Init(const char dir[], UINT4)
Setup SEOBNRv4HMROM mode using data files installed in dir.
static UNUSED UINT8 SEOBNRv4HMROM_phase_sparse_grid_hybrid_output_align(gsl_vector **freq, gsl_vector **phase, REAL8 *Deltat_align, REAL8 *Deltaphi_align, gsl_vector *phase_lo, gsl_vector *phase_hi, gsl_vector *freq_lo, gsl_vector *freq_hi, double f_hyb_lo, double f_hyb_hi)
static UNUSED int TaylorF2Phasing(double Mtot, double q, double chi1, double chi2, int l, int m, gsl_vector *Mfs, gsl_vector **PNphase)
int(* load_dataPtr)(const char *, gsl_vector *, gsl_vector *, gsl_matrix *, gsl_matrix *, gsl_vector *)
static UNUSED UINT8 SEOBNRv4HMROM_phase_sparse_grid_hybrid_input_align(gsl_vector **freq, gsl_vector **phase, gsl_vector *phase_lo, gsl_vector *phase_hi, gsl_vector *freq_lo, gsl_vector *freq_hi, double f_hyb_lo, double f_hyb_hi, REAL8 Deltat_22_align, REAL8 Deltaphi_22_align, INT4 modeM)
static UNUSED double GetDeltaphilm(int l, int m)
static UNUSED int SEOBNRv4HMROMCoreModesHybridized(UNUSED SphHarmFrequencySeries **hlm_list, UNUSED REAL8 phiRef, UNUSED REAL8 fRef, UNUSED REAL8 distance, UNUSED REAL8 Mtot_sec, UNUSED REAL8 q, UNUSED REAL8 chi1, UNUSED REAL8 chi2, UNUSED const REAL8Sequence *freqs_in, UNUSED REAL8 deltaF, UNUSED INT4 nk_max, UNUSED UINT4 nModes, REAL8 sign_odd_modes)
static UNUSED void SplineData_Init(SplineData **splinedata, int ncx, int ncy, int ncz, const double *qvec, const double *chi1vec, const double *chi2vec)
static UNUSED int hybridize_ROM_with_PN_phase_output_align(gsl_spline **hyb_spline, REAL8 *Deltat_align, REAL8 *Deltaphi_align, AmpPhaseSplineData *ampPhaseSplineData_for_mode, gsl_vector *PN_freq, gsl_vector *PN_phase, double f_hyb_win_lo, double f_hyb_win_hi)
static UNUSED int SEOBNRROMdataDS_Init(SEOBNRROMdataDS *romdata, const char dir[], UINT4)
static UNUSED UINT8 SEOBNRv4HMROM_phase_sparse_grid_hybrid(gsl_vector *freq, gsl_vector *phase, gsl_vector *freq_lo, gsl_vector *freq_hi, REAL8 q, REAL8 chi1, REAL8 chi2, INT4 nk_max)
const REAL8 const_phaseshift_lm[NMODES]
static UNUSED void SplineData_Destroy(SplineData *splinedata)
const char mode_array[NMODES][3]
const REAL8 const_fmax_lm[NMODES]
static UNUSED int SEOBNRROMdataDS_Init_submodel(UNUSED SEOBNRROMdataDS_submodel **submodel, UNUSED const char dir[], UNUSED const char grp_name[], UINT4 index_mode)
static UNUSED UINT8 SEOBNRv4HMROM_amplitude_sparse_grid_hybrid_general(gsl_vector **freq, gsl_vector **amp, gsl_vector *amp_lo, gsl_vector *amp_hi, gsl_vector *freq_lo, gsl_vector *freq_hi, double f_hyb_lo, double f_hyb_hi)
static UNUSED UINT8 SEOBNRv4HMROM_cmode_sparse_grid(gsl_vector *creal_f, gsl_vector *cimag_f, REAL8 q, REAL8 chi1, REAL8 chi2, const char *freq_range, UINT8 nMode, INT4 nk_max)
static UNUSED UINT8 SEOBNRv4HMROM_freq_phase_sparse_grid_hybrid(UNUSED gsl_vector **freq, UNUSED gsl_vector **phase, REAL8 q, REAL8 chi1, REAL8 chi2, UINT8 flag_patch, INT4 nk_max)
static UNUSED void SEOBNRROMdataDS_coeff_Init(SEOBNRROMdataDS_coeff **romdatacoeff, int nk_cmode, int nk_phase)
static UNUSED int TaylorF2Amplitude(const double q, const double chi1, const double chi2, const int l, const int m, gsl_vector *Mfs, gsl_vector **PNamp)
static int SEOBROMComputehplushcrossFromhlm(COMPLEX16FrequencySeries *hplusFS, COMPLEX16FrequencySeries *hcrossFS, LALValue *ModeArray, SphHarmFrequencySeries *hlm, REAL8 inc, REAL8 phi)
static UNUSED void SEOBNRv4HMROM_Init_LALDATA(void)
Setup SEOBNRv4HMROM model using data files installed in $LAL_DATA_PATH.
static UNUSED void SEOBNRROMdataDS_Cleanup_submodel(SEOBNRROMdataDS_submodel *submodel)
static UNUSED void AmpPhaseSplineData_Init(AmpPhaseSplineData ***data, const int num_modes)
const UINT4 lmModes[NMODES][2]
static UNUSED void SEOBNRROMdataDS_coeff_Cleanup(SEOBNRROMdataDS_coeff *romdatacoeff)
static UNUSED UINT8 SEOBNRv4HMROM_cmode_sparse_grid_hybrid(gsl_vector *freq, gsl_vector *cmode_real, gsl_vector *cmode_imag, gsl_vector *freq_lo, gsl_vector *freq_hi, REAL8 q, REAL8 chi1, REAL8 chi2, UINT8 nMode, INT8 nk_max)
static UNUSED void SEOBNRROMdataDS_Cleanup(SEOBNRROMdataDS *romdata)
static UNUSED int hybridize_ROM_with_PN_amplitude(gsl_spline **hyb_spline, AmpPhaseSplineData *ampPhaseSplineData_for_mode, gsl_vector *PN_freq, gsl_vector *PN_amp, double f_hyb_win_lo, double f_hyb_win_hi)
static UNUSED double GetModeAmpFactor(double eta, double delta, double chi1, double chi2, int l, int m, double v)
static size_t NextPow2(const size_t n)
static UNUSED int BuildInspiralGeomFrequencyGrid(gsl_vector **Mfreq, const double Mfmin, const double Mfmax, const double q, const double acc)
static UNUSED UINT8 SEOBNRv4HMROM_approx_phi_lm(gsl_vector *freq_mode_lm, gsl_vector *phase_approx_lm, gsl_vector *freq_carrier_hyb, gsl_vector *phase_carrier_hyb, UINT4 nMode)
static int TP_Spline_interpolation_3d(REAL8 q, REAL8 chi1, REAL8 chi2, gsl_vector *cvec, int nk, int nk_max, int ncx, int ncy, int ncz, const double *qvec, const double *chi1vec, const double *chi2vec, gsl_vector *c_out)
static UNUSED UINT8 SEOBNRv4HMROM_phase_sparse_grid(gsl_vector *phase_f, REAL8 q, REAL8 chi1, REAL8 chi2, const char *freq_range, INT4 nk_max)
static UNUSED int SEOBNRv4HMROMCoreModeAmpPhaseSplines(UNUSED AmpPhaseSplineData **ampPhaseSplineData, UNUSED REAL8 q, UNUSED REAL8 chi1, UNUSED REAL8 chi2, UNUSED INT4 nk_max, UNUSED UINT4 nModes)
static UNUSED int hybridize_ROM_with_PN_phase_input_align(gsl_spline **hyb_spline, AmpPhaseSplineData *ampPhaseSplineData_for_mode, gsl_vector *PN_freq, gsl_vector *PN_phase, double f_hyb_win_lo, double f_hyb_win_hi, REAL8 Deltat_22_align, REAL8 Deltaphi_22_align, INT4 modeM)
static UNUSED int SEOBNRv4HMROMCoreModes(SphHarmFrequencySeries **hlm_list, REAL8 phiRef, REAL8 fRef, REAL8 distance, REAL8 Mtot_sec, REAL8 q, REAL8 chi1, REAL8 chi2, const REAL8Sequence *freqs, REAL8 deltaF, INT4 nk_max, UINT4 nModes, REAL8 sign_odd_modes)
Core function for computing the ROM waveform.
static UINT8 Setup_EOBROM__std_mode_array_structure(LALValue *ModeArray, UINT4 nModes)
ModeArray is a structure which allows to select the modes to include in the waveform.
const REAL8 Mf_low_lm[NMODES]
static UNUSED int spline_to_gsl_vectors(gsl_spline *s, gsl_vector **x, gsl_vector **y)
void XLALDestroyValue(LALValue *value)
#define XLAL_FILE_RESOLVE_PATH(fname)
COMPLEX16FrequencySeries * XLALCreateCOMPLEX16FrequencySeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaF, const LALUnit *sampleUnits, size_t length)
void XLALDestroyCOMPLEX16FrequencySeries(COMPLEX16FrequencySeries *series)
void XLALH5FileClose(LALH5File UNUSED *file)
LALH5File * XLALH5GroupOpen(LALH5File UNUSED *file, const char UNUSED *name)
LALH5File * XLALH5FileOpen(const char UNUSED *path, const char UNUSED *mode)
void * XLALMalloc(size_t n)
void * XLALCalloc(size_t m, size_t n)
int XLALSimIMRSEOBNRv4HMROM(UNUSED struct tagCOMPLEX16FrequencySeries **hptilde, UNUSED struct tagCOMPLEX16FrequencySeries **hctilde, UNUSED REAL8 phiRef, UNUSED REAL8 deltaF, REAL8 fLow, UNUSED REAL8 fHigh, UNUSED REAL8 fRef, UNUSED REAL8 distance, UNUSED REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2, UNUSED INT4 nk_max, UNUSED UINT4 nModes, bool use_hybridization, LALDict *LALParams)
Compute waveform in LAL format for the SEOBNRv4HM_ROM model.
int XLALSimIMRSEOBNRv4HMROMFrequencySequence(UNUSED struct tagCOMPLEX16FrequencySeries **hptilde, UNUSED struct tagCOMPLEX16FrequencySeries **hctilde, const REAL8Sequence *freqs, UNUSED REAL8 phiRef, UNUSED REAL8 fRef, UNUSED REAL8 distance, UNUSED REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2, UNUSED INT4 nk_max, UNUSED UINT4 nModes, LALDict *LALParams)
Compute waveform polarizations at user specified frequencies for the SEOBNRv4HM_ROM model.
int XLALSimIMRSEOBNRv4HMROM_Modes(SphHarmFrequencySeries **hlm, UNUSED REAL8 phiRef, UNUSED REAL8 deltaF, REAL8 fLow, UNUSED REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2, UNUSED INT4 nk_max, UNUSED UINT4 nModes, bool use_hybridization)
Compute modes in LAL format for the SEOBNRv4HM_ROM model.
int XLALSimIMRSEOBNRv4HMROMFrequencySequence_Modes(SphHarmFrequencySeries **hlm, const REAL8Sequence *freqs, UNUSED REAL8 phiRef, UNUSED REAL8 fRef, UNUSED REAL8 distance, UNUSED REAL8 inclination, REAL8 m1SI, REAL8 m2SI, REAL8 chi1, REAL8 chi2, UNUSED INT4 nk_max, UNUSED UINT4 nModes, LALDict *LALParams)
Compute waveform modes at user specified frequencies for the SEOBNRv4HM_ROM model.
#define LAL_SIM_L_MAX_MODE_ARRAY
Maximum L spherical harmonic mode that is supported in Mode Array.
@ LAL_SIM_INSPIRAL_SPIN_ORDER_35PN
int XLALSimInspiralTaylorF2AlignedPhasing(PNPhasingSeries **pfa, const REAL8 m1, const REAL8 m2, const REAL8 chi1, const REAL8 chi2, LALDict *extraPars)
Returns structure containing TaylorF2 phasing coefficients for given physical parameters.
int XLALSimAddModeFD(COMPLEX16FrequencySeries *hptilde, COMPLEX16FrequencySeries *hctilde, COMPLEX16FrequencySeries *hlmtilde, REAL8 theta, REAL8 phi, INT4 l, INT4 m, INT4 sym)
Helper function to add a mode to hplus, hcross in Fourier domain copies the function XLALSimAddMode,...
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 XLALDestroyREAL8Sequence(REAL8Sequence *sequence)
REAL8Sequence * XLALCreateREAL8Sequence(size_t length)
const LALUnit lalStrainUnit
const LALUnit lalSecondUnit
LALUnit * XLALUnitDivide(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
LALUnit * XLALUnitMultiply(LALUnit *output, const LALUnit *unit1, const LALUnit *unit2)
#define XLAL_ERROR_VOID(...)
#define XLAL_PRINT_INFO(...)
int int int XLALPrintInfo(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_CHECK(assertion,...)
int XLALPrintError(const char *fmt,...) _LAL_GCC_PRINTF_FORMAT_(1
#define XLAL_PRINT_ERROR(...)
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
gsl_interp_accel * acc_amp
gsl_interp_accel * acc_phi
struct tagSphHarmFrequencySeries * next
next pointer
COMPLEX16FrequencySeries * mode
The sequences of sampled data.
gsl_bspline_workspace * bwx
gsl_bspline_workspace * bwz
gsl_bspline_workspace * bwy
SEOBNRROMdataDS_submodel * lqhs
SEOBNRROMdataDS_submodel * lowf
SEOBNRROMdataDS_submodel * hqhs
SEOBNRROMdataDS_submodel * hqls
SEOBNRROMdataDS_submodel * lqls