56 #define UNUSED __attribute__ ((unused))
66 #include <lal/FileIO.h>
67 #include <lal/SphericalHarmonics.h>
68 #include <lal/H5FileIO.h>
71 #ifdef LAL_PTHREAD_LOCK
75 #ifdef LAL_PTHREAD_LOCK
76 static pthread_once_t NRHybSur3dq8_is_initialized = PTHREAD_ONCE_INIT;
118 "Unable to find data file %s in $LAL_DATA_PATH\n",
123 char *dir = dirname(
path);
131 "Unable to load data file %s in $LAL_DATA_PATH."
156 gsl_vector* fit_params,
163 const REAL8 chi_wtAvg = (
q*chi1z+chi2z)/(1.+
q);
165 = (chi_wtAvg - 38.*eta/113.*(chi1z + chi2z))/(1. - 76.*eta/113.);
166 const REAL8 chi_a = (chi1z - chi2z)/2.;
169 "NRHybSur3dq8_fitParams(): size of fit_params should be 3, not %zu.\n",
172 gsl_vector_set(fit_params, 0, log(
q));
173 gsl_vector_set(fit_params, 1, chiHat);
174 gsl_vector_set(fit_params, 2, chi_a);
240 const REAL8 Mtot_sec,
249 REAL8 init_orbphase = 0;
266 const char *param_validity =
"This model is valid for q <= 9.1 & "
267 "|chi1z,chi2z| <= 0.91, or q <= 10.1 & |chi1z,chi2z| <= 0.81";
270 UINT4 unlim_extrap = 0;
271 if (LALparams != NULL &&
279 if ((
q > 10.1) && (unlim_extrap == 0)) {
281 "Too much extrapolation in mass ratio; q=%0.4f > 10.1\n%s\n",
q,
286 "Extrapolating outside training range q=%0.4f > 8.1\n",
q);
288 if ((fabs(chi1z) > 0.91) && (unlim_extrap == 0)) {
290 "Too much extrapolation; |chi1z|=%0.4f > 0.91\n%s\n", fabs(chi1z),
293 if ((fabs(chi2z) > 0.91) && (unlim_extrap == 0)) {
295 "Too much extrapolation; |chi2z|=%0.4f > 0.91\n%s\n", fabs(chi2z),
298 if (fabs(chi1z) > 0.81) {
299 if ((
q > 9.1) && (unlim_extrap == 0)) {
301 "Too much extrapolation; q=%0.4f > 9.1 & |chi1z|=%.04f"
302 " >0.81\n%s\n",
q, fabs(chi1z), param_validity);
305 "Extrapolating outside training range |chi1z|=%0.4f > 0.81\n",
308 if (fabs(chi2z) > 0.81) {
309 if ((
q > 9.1) && (unlim_extrap == 0)) {
311 "Too much extrapolation; q=%0.4f > 9.1 & |chi2z|=%.04f"
312 " >0.81\n%s\n",
q, fabs(chi2z), param_validity);
315 "Extrapolating outside training range |chi2z|=%0.4f > 0.81\n",
325 const REAL8 omegaM_22_min = 2*
LAL_PI*fMin*Mtot_sec;
331 omegaM_22_ref = omegaM_22_min;
334 omegaM_22_ref = 2*
LAL_PI*fRef*Mtot_sec;
341 gsl_vector *fit_params = gsl_vector_alloc(NR_hybsur_data->
params_dim);
348 const gsl_matrix *x_train = NR_hybsur_data->
x_train;
351 const gsl_vector *domain = NR_hybsur_data->
domain;
354 gsl_vector *dummy_worker = gsl_vector_alloc(NR_hybsur_data->
params_dim);
355 gsl_vector *dummy_dp = gsl_vector_alloc(domain->size);
357 gsl_vector *output_times = NULL;
367 omegaM_22_min, deltaTOverM, init_orbphase, omegaM_22_ref, dummy_dp,
368 x_train, dummy_worker, NR_hybsur_data);
371 "Failed to evaluate phi_22 data piece");
376 const REAL8 t0 = gsl_vector_get(output_times, 0);
380 const gsl_matrix_long *mode_list = NR_hybsur_data->
mode_list;
382 UINT4 incl_mode_idx = 0;
383 for (
UINT4 mode_idx = 0; mode_idx < num_modes_modeled; mode_idx++){
385 const UINT4 ell = gsl_matrix_long_get(mode_list, mode_idx, 0);
386 const UINT4 m = gsl_matrix_long_get(mode_list, mode_idx, 1);
394 if((ell != data_pieces->
ell) || (
m != data_pieces->
m)){
398 evaluated_mode_dps[incl_mode_idx]
403 &evaluated_mode_dps[incl_mode_idx], ell,
m,
404 data_pieces, output_times, fit_params, dummy_dp,
405 x_train, dummy_worker, NR_hybsur_data);
408 "Failed to evaluate (%u, %u) mode", ell,
m);
415 gsl_vector_free(fit_params);
416 gsl_vector_free(dummy_dp);
417 gsl_vector_free(dummy_worker);
418 gsl_vector_free(output_times);
493 #ifdef LAL_PTHREAD_LOCK
502 if (NR_hybsur_data->
setup != 1){
509 if (ModeArray == NULL) {
516 UINT4 num_modes_incl, max_ell;
542 gsl_vector *phi_22 = NULL;
547 =
XLALMalloc(num_modes_incl *
sizeof(*evaluated_mode_dps));
554 ModeArray, LALparams);
559 const UINT4 num_times = phi_22->size;
579 for (
UINT4 mode_idx = 0; mode_idx < num_modes_incl; mode_idx++){
582 ell = this_mode_eval_dp->
ell;
583 m = this_mode_eval_dp->
m;
595 0.5 *
LAL_PI - phiRef, -2, ell,
m);
604 0.5 *
LAL_PI - phiRef, -2, ell, -
m);
607 for (
UINT4 j=0; j < num_times; j++) {
612 const REAL8 tmp_phi_22 = gsl_vector_get(phi_22, j);
614 if (ell == 2 &&
m ==2){
615 const REAL8 tmp_Amp_22 = gsl_vector_get(
618 hlm = tmp_Amp_22 * (cos(tmp_phi_22) - I*sin(tmp_phi_22));
624 REAL8 coorb_hlm_re = 0.0;
625 REAL8 coorb_hlm_im = 0.0;
629 if (
m != 0 || ell % 2 == 0) {
630 coorb_hlm_re = gsl_vector_get(
636 if (
m != 0 || ell % 2 == 1) {
637 coorb_hlm_im = gsl_vector_get(
644 hlm = (coorb_hlm_re + I * coorb_hlm_im)
645 * (cos(
m*tmp_phi_22/2.) - I*sin(
m*tmp_phi_22/2.));
648 hcomplex = hlm * swsh_coef;
658 hcomplex += pre_factor * conj(hlm) * swsh_coef_negM;
662 hPlusTS->
data->
data[j] += creal(hcomplex) * a0;
663 hCrossTS->
data->
data[j] -= cimag(hcomplex) * a0;
669 (*hcross) = hCrossTS;
742 #ifdef LAL_PTHREAD_LOCK
751 if (NR_hybsur_data->
setup != 1){
758 if (ModeArray == NULL) {
765 UINT4 num_modes_incl, max_ell;
791 gsl_vector *phi_22 = NULL;
796 =
XLALMalloc(num_modes_incl *
sizeof(*evaluated_mode_dps));
803 ModeArray, LALparams);
808 const UINT4 num_times = phi_22->size;
815 for (
UINT4 mode_idx = 0; mode_idx < num_modes_incl; mode_idx++){
818 ell = this_mode_eval_dp->
ell;
819 m = this_mode_eval_dp->
m;
821 snprintf(mode_name,
sizeof(mode_name),
"(%u, %u) mode", ell,
m);
825 for (
UINT4 j=0; j < num_times; j++) {
827 const REAL8 tmp_phi_22 = gsl_vector_get(phi_22, j);
829 if (ell == 2 &&
m ==2){
830 const REAL8 tmp_Amp_22 = gsl_vector_get(
835 = a0* tmp_Amp_22 * (cos(tmp_phi_22) - I*sin(tmp_phi_22));
841 REAL8 coorb_hlm_re = 0.0;
842 REAL8 coorb_hlm_im = 0.0;
846 if (
m != 0 || ell % 2 == 0) {
847 coorb_hlm_re = gsl_vector_get(
853 if (
m != 0 || ell % 2 == 1) {
854 coorb_hlm_im = gsl_vector_get(
862 = a0 * (coorb_hlm_re + I * coorb_hlm_im)
863 * (cos(
m*tmp_phi_22/2.) - I*sin(
m*tmp_phi_22/2.));
struct tagLALH5File LALH5File
int XLALDictContains(const LALDict *dict, const char *key)
UINT4 XLALDictLookupUINT4Value(LALDict *dict, const char *key)
int NRHybSur3dq8_fitParams(gsl_vector *fit_params, const REAL8 q, const REAL8 chi1z, const REAL8 chi2z)
Map from mass ratio and spins to surrogate fit parameters.
static bool NRHybSur3dq8_IsSetup(void)
Helper function to check if the NRHybSur3dq8 model has been initialized.
int NRHybSur3dq8_core(gsl_vector **phi_22, EvaluatedDataPieces **evaluated_mode_dps, LIGOTimeGPS *epoch, const REAL8 deltaT, const REAL8 fMin, const REAL8 fRef, REAL8 q, const REAL8 Mtot_sec, REAL8 chi1z, REAL8 chi2z, LALValue *ModeArray, LALDict *LALparams)
This is the core function of the NRHybSur3dq8 model.
static void NRHybSur3dq8_Init_LALDATA(void)
Surrogate initialization.
INT4 XLALSimIMRNRHybSur3dq8Polarizations(REAL8TimeSeries **hplus, REAL8TimeSeries **hcross, REAL8 phiRef, REAL8 inclination, REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 distance, REAL8 fMin, REAL8 fRef, REAL8 chi1z, REAL8 chi2z, LALDict *LALparams)
Reference: arxiv:1812.07865.
SphHarmTimeSeries * XLALSimIMRNRHybSur3dq8Modes(REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 chi1z, REAL8 chi2z, REAL8 fMin, REAL8 fRef, REAL8 distance, LALDict *LALparams)
Reference: arxiv:1812.07865.
static NRHybSurData __lalsim_NRHybSur3dq8_data
Global surrogate data.
C code for NRHybSur3dq8 waveform model, an NR-hybrid surrogate model for aligned-spin BBH.
static const char NRHybSur3dq8_DATAFILE[]
int NRHybSur_check_mode_array(UINT4 *num_modes_incl, UINT4 *max_ell, LALValue *ModeArray, const NRHybSurData *NR_hybsur_data)
Sanity checks on ModeArray.
void NRHybSur_set_default_modes(LALValue *ModeArray, const NRHybSurData *NR_hybsur_data)
Activates all modes of an NRHybSur model.
int NRHybSur_eval_phase_22(gsl_vector **phi_22, gsl_vector **output_times, const REAL8 eta, const gsl_vector *fit_params, const REAL8 omegaM_22_min, const REAL8 deltaTOverM, const REAL8 phiRef, const REAL8 omegaM_22_ref, gsl_vector *dummy_dp, const gsl_matrix *x_train, gsl_vector *dummy_worker, const NRHybSurData *NR_hybsur_data)
Evaluate the phase of the (2,2) mode.
int NRHybSur_eval_mode_data_pieces(EvaluatedDataPieces **this_mode_eval_dp, const UINT4 ell, const UINT4 m, const ModeDataPieces *data_pieces, const gsl_vector *output_times, const gsl_vector *fit_params, gsl_vector *dummy_dp, const gsl_matrix *x_train, gsl_vector *dummy_worker, const NRHybSurData *NR_hybsur_data)
Evaluate waveform data pieces of a single mode.
int NRHybSur_sanity_check_sample_rate(REAL8 deltaT, REAL8 m1, REAL8 m2, REAL8 chi1z, REAL8 chi2z, UINT4 max_ell)
Sanity check (warning only, not error) that the sample rate is high enough to capture the ringdown fr...
void NRHybSur_DestroyEvaluatedDataPieces(gsl_vector *phi_22, EvaluatedDataPieces **evaluated_mode_dps, const UINT4 num_modes_incl)
Destroy phi_22 and an EvaluatedDataPieces structure.
int NRHybSur_Init(NRHybSurData *NR_hybsur_data, LALH5File *file)
Initialize a NRHybSurData structure from an open H5 file.
void XLALDestroyValue(LALValue *value)
#define XLAL_FILE_RESOLVE_PATH(fname)
void XLALH5FileClose(LALH5File UNUSED *file)
LALH5File * XLALH5FileOpen(const char UNUSED *path, const char UNUSED *mode)
void * XLALMalloc(size_t n)
SphHarmTimeSeries * XLALSphHarmTimeSeriesAddMode(SphHarmTimeSeries *appended, const COMPLEX16TimeSeries *inmode, UINT4 l, INT4 m)
Prepend a node to a linked list of SphHarmTimeSeries, or create a new head.
COMPLEX16 XLALSpinWeightedSphericalHarmonic(REAL8 theta, REAL8 phi, int s, int l, int m)
REAL8TimeSeries * XLALCreateREAL8TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
void XLALDestroyCOMPLEX16TimeSeries(COMPLEX16TimeSeries *series)
COMPLEX16TimeSeries * XLALCreateCOMPLEX16TimeSeries(const CHAR *name, const LIGOTimeGPS *epoch, REAL8 f0, REAL8 deltaT, const LALUnit *sampleUnits, size_t length)
const LALUnit lalStrainUnit
#define XLAL_ERROR_VOID(...)
#define XLAL_ERROR_NULL(...)
#define XLAL_CHECK(assertion,...)
#define XLAL_PRINT_WARNING(...)
LIGOTimeGPS * XLALGPSAdd(LIGOTimeGPS *epoch, REAL8 dt)
int pthread_once(pthread_once_t *once_control, void(*init_routine)(void))
NRHybSur evaluated data for a single mode.
gsl_vector * coorb_re_eval
Coorbital frame real part evaluation.
gsl_vector * ampl_eval
Amplitude data piece evaluation.
gsl_vector * coorb_im_eval
Coorbital frame imag part evaluation.
NRHybSur data pieces of a single mode.
NRHybSur surrogate data for all modes, to be loaded from a h5 file.
ModeDataPieces ** mode_data_pieces
Data pieces of all modes, same order as mode_list.
gsl_vector * domain
Common time samples for the surrogate.
REAL8 params_dim
Dimensions of the model.
UINT4 setup
Indicates if NRHybSur has been initialized.
gsl_matrix * x_train
Training set parameters, needed for GPR fits.
UINT4 num_modes_modeled
Number of modeled modes.
gsl_matrix_long * mode_list
List of modeled modes, first element is always (2,2).
Structure to carry a collection of spherical harmonic modes in COMPLEX16 time series.