double CalibratorGaussian::my_f(const gsl_vector *v, void *params) { double x, y; double *p = (double *)params; int N = p[0]; double* obs = p + 1; double* mean = p + 1 + N; double* spread = p + 1 + 2*N; const double* arr = gsl_vector_const_ptr(v, 0); std::vector<float> vec(arr, arr+mNumParameters); Parameters par(vec); float sa = gsl_vector_get(v, 0); float sb = gsl_vector_get(v, 1); float total = 0; for(int n = 0; n < N; n++) { float pdf = getPdf(obs[n], mean[n], spread[n], par); // std::cout << " " << obs[n] << " " << mean[n] << std::endl; if(pdf == 0 || !Util::isValid(pdf)) pdf = 0.00001; assert(pdf > 0); total += log(pdf); } // std::cout << "Log likelihood: " << total << std::endl; return -total; }
const double* cbegin(const GSL_vector& v) { if (v.size()) return gsl_vector_const_ptr(v.raw(), 0); return nullptr; }
void Geo3d_Cov_Orientation(double *cov, double *vec, double *ext) { #ifdef HAVE_LIBGSL gsl_matrix_view gmv = gsl_matrix_view_array(cov, 3, 3); gsl_vector *eval = gsl_vector_alloc(3); gsl_matrix *evec = gsl_matrix_alloc(3,3); gsl_eigen_symmv_workspace *w = gsl_eigen_symmv_alloc(3); gsl_eigen_symmv(&(gmv.matrix), eval, evec, w); gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_VAL_DESC); if(ext != NULL) { darraycpy(ext, gsl_vector_const_ptr(eval, 0), 0, 3); } gsl_vector_view v = gsl_vector_view_array(vec, 3); gsl_matrix_get_col(&(v.vector), evec, 0); gsl_vector_free(eval); gsl_matrix_free(evec); gsl_eigen_symmv_free(w); #else double eigv[3]; Matrix_Eigen_Value_Cs(cov[0], cov[4], cov[8], cov[1], cov[2], cov[5], eigv); Matrix_Eigen_Vector_Cs(cov[0], cov[4], cov[8], cov[1], cov[2], cov[5], eigv[0], vec); if(ext != NULL) { darraycpy(ext, eigv, 0, 3); } #endif }
const double* cend(const GSL_vector& v) { if (v.size()) { const double* last = gsl_vector_const_ptr(v.raw(), v.size() - 1); return ++last; } return nullptr; }
/** Get i-th element */ double vector<double>::operator()(const size_t& i) const { const double *x = gsl_vector_const_ptr(_vector, i); return *x; }
const double& GslVector::operator[](unsigned int i) const { return *gsl_vector_const_ptr(m_vec,i); }
const double& vector::operator[](size_t off) const { if (!ptr_) throw std::runtime_error("empty gsl::vector"); return *gsl_vector_const_ptr(ptr_, off); }
/** * Core function for computing the ROM waveform. * Interpolate projection coefficient data and evaluate coefficients at desired (q, chi). * Construct 1D splines for amplitude and phase. * Compute strain waveform from amplitude and phase. */ static int SEOBNRv1ROMEffectiveSpinCore( COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, double phiRef, double fRef, double distance, double inclination, double Mtot_sec, double q, double chi, const REAL8Sequence *freqs_in, /* Frequency points at which to evaluate the waveform (Hz) */ double deltaF /* If deltaF > 0, the frequency points given in freqs are uniformly spaced with * spacing deltaF. Otherwise, the frequency points are spaced non-uniformly. * Then we will use deltaF = 0 to create the frequency series we return. */ ) { /* Check output arrays */ if(!hptilde || !hctilde) XLAL_ERROR(XLAL_EFAULT); SEOBNRROMdata *romdata=&__lalsim_SEOBNRv1ROMSS_data; if(*hptilde || *hctilde) { XLALPrintError("(*hptilde) and (*hctilde) are supposed to be NULL, but got %p and %p",(*hptilde),(*hctilde)); XLAL_ERROR(XLAL_EFAULT); } int retcode=0; // 'Nudge' parameter values to allowed boundary values if close by if (q < 1.0) nudge(&q, 1.0, 1e-6); if (q > 100.0) nudge(&q, 100.0, 1e-6); if (chi < -1.0) nudge(&chi, -1.0, 1e-6); if (chi > 0.6) nudge(&chi, 0.6, 1e-6); /* If either spin > 0.6, model not available, exit */ if ( chi < -1.0 || chi > 0.6 ) { XLALPrintError( "XLAL Error - %s: chi smaller than -1 or larger than 0.6!\nSEOBNRv1ROMEffectiveSpin is only available for spins in the range -1 <= a/M <= 0.6.\n", __func__); XLAL_ERROR( XLAL_EDOM ); } if (q > 100) { XLALPrintError( "XLAL Error - %s: q=%lf larger than 100!\nSEOBNRv1ROMEffectiveSpin is only available for q in the range 1 <= q <= 100.\n", __func__,q); XLAL_ERROR( XLAL_EDOM ); } if (q >= 20 && q <= 40 && chi < -0.75 && chi > -0.9) { XLALPrintWarning( "XLAL Warning - %s: q in [20,40] and chi in [-0.8]. The SEOBNRv1 model is not trustworthy in this region!\nSee Fig 15 in CQG 31 195010, 2014 for details.", __func__); XLAL_ERROR( XLAL_EDOM ); } /* Find frequency bounds */ if (!freqs_in) XLAL_ERROR(XLAL_EFAULT); double fLow = freqs_in->data[0]; double fHigh = freqs_in->data[freqs_in->length - 1]; if(fRef==0.0) fRef=fLow; /* Convert to geometric units for frequency */ double Mf_ROM_min = fmax(gA[0], gPhi[0]); // lowest allowed geometric frequency for ROM double Mf_ROM_max = fmin(gA[nk_amp-1], gPhi[nk_phi-1]); // highest allowed geometric frequency for ROM double fLow_geom = fLow * Mtot_sec; double fHigh_geom = fHigh * Mtot_sec; double fRef_geom = fRef * Mtot_sec; double deltaF_geom = deltaF * Mtot_sec; // Enforce allowed geometric frequency range if (fLow_geom < Mf_ROM_min) XLAL_ERROR(XLAL_EDOM, "Starting frequency Mflow=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min); if (fHigh_geom == 0) fHigh_geom = Mf_ROM_max; else if (fHigh_geom > Mf_ROM_max) { XLALPrintWarning("Maximal frequency Mf_high=%g is greater than highest ROM frequency Mf_ROM_Max=%g. Using Mf_high=Mf_ROM_Max.", fHigh_geom, Mf_ROM_max); fHigh_geom = Mf_ROM_max; } else if (fHigh_geom < Mf_ROM_min) XLAL_ERROR(XLAL_EDOM, "End frequency %g is smaller than starting frequency %g!\n", fHigh_geom, fLow_geom); if (fRef_geom > Mf_ROM_max) { XLALPrintWarning("Reference frequency Mf_ref=%g is greater than maximal frequency in ROM Mf=%g. Starting at maximal frequency in ROM.\n", fRef_geom, Mf_ROM_max); fRef_geom = Mf_ROM_max; // If fref > fhigh we reset fref to default value of cutoff frequency. } if (fRef_geom < Mf_ROM_min) { XLALPrintWarning("Reference frequency Mf_ref=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min); fRef_geom = Mf_ROM_min; } /* Internal storage for w.f. coefficiencts */ SEOBNRROMdata_coeff *romdata_coeff=NULL; SEOBNRROMdata_coeff_Init(&romdata_coeff); REAL8 amp_pre; /* Interpolate projection coefficients and evaluate them at (q,chi) */ retcode=TP_Spline_interpolation_2d( q, // Input: q-value for which projection coefficients should be evaluated chi, // Input: chi-value for which projection coefficients should be evaluated romdata->cvec_amp, // Input: data for spline coefficients for amplitude romdata->cvec_phi, // Input: data for spline coefficients for phase romdata->cvec_amp_pre, // Input: data for spline coefficients for amplitude prefactor romdata_coeff->c_amp, // Output: interpolated projection coefficients for amplitude romdata_coeff->c_phi, // Output: interpolated projection coefficients for phase &_pre // Output: interpolated amplitude prefactor ); if(retcode!=0) { SEOBNRROMdata_coeff_Cleanup(romdata_coeff); XLAL_ERROR(retcode, "Parameter-space interpolation failed."); } // Compute function values of amplitude an phase on sparse frequency points by evaluating matrix vector products // amp_pts = B_A^T . c_A // phi_pts = B_phi^T . c_phi gsl_vector* amp_f = gsl_vector_alloc(nk_amp); gsl_vector* phi_f = gsl_vector_alloc(nk_phi); gsl_blas_dgemv(CblasTrans, 1.0, romdata->Bamp, romdata_coeff->c_amp, 0.0, amp_f); gsl_blas_dgemv(CblasTrans, 1.0, romdata->Bphi, romdata_coeff->c_phi, 0.0, phi_f); // Setup 1d splines in frequency gsl_interp_accel *acc_amp = gsl_interp_accel_alloc(); gsl_spline *spline_amp = gsl_spline_alloc(gsl_interp_cspline, nk_amp); gsl_spline_init(spline_amp, gA, gsl_vector_const_ptr(amp_f,0), nk_amp); gsl_interp_accel *acc_phi = gsl_interp_accel_alloc(); gsl_spline *spline_phi = gsl_spline_alloc(gsl_interp_cspline, nk_phi); gsl_spline_init(spline_phi, gPhi, gsl_vector_const_ptr(phi_f,0), nk_phi); size_t npts = 0; LIGOTimeGPS tC = {0, 0}; UINT4 offset = 0; // Index shift between freqs and the frequency series REAL8Sequence *freqs = NULL; if (deltaF > 0) { // freqs contains uniform frequency grid with spacing deltaF; we start at frequency 0 /* Set up output array with size closest power of 2 */ npts = NextPow2(fHigh_geom / deltaF_geom) + 1; if (fHigh_geom < fHigh * Mtot_sec) /* Resize waveform if user wants f_max larger than cutoff frequency */ npts = NextPow2(fHigh * Mtot_sec / deltaF_geom) + 1; XLALGPSAdd(&tC, -1. / deltaF); /* coalesce at t=0 */ *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, npts); *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, npts); // Recreate freqs using only the lower and upper bounds UINT4 iStart = (UINT4) ceil(fLow_geom / deltaF_geom); UINT4 iStop = (UINT4) ceil(fHigh_geom / deltaF_geom); freqs = XLALCreateREAL8Sequence(iStop - iStart); if (!freqs) { XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed."); } for (UINT4 i=iStart; i<iStop; i++) freqs->data[i-iStart] = i*deltaF_geom; offset = iStart; } else { // freqs contains frequencies with non-uniform spacing; we start at lowest given frequency npts = freqs_in->length; *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, fLow, 0, &lalStrainUnit, npts); *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, fLow, 0, &lalStrainUnit, npts); offset = 0; freqs = XLALCreateREAL8Sequence(freqs_in->length); if (!freqs) { XLAL_ERROR(XLAL_EFUNC, "Frequency array allocation failed."); } for (UINT4 i=0; i<freqs_in->length; i++) freqs->data[i] = freqs_in->data[i] * Mtot_sec; } if (!(*hptilde) || !(*hctilde)) { XLALDestroyREAL8Sequence(freqs); gsl_spline_free(spline_amp); gsl_spline_free(spline_phi); gsl_interp_accel_free(acc_amp); gsl_interp_accel_free(acc_phi); gsl_vector_free(amp_f); gsl_vector_free(phi_f); SEOBNRROMdata_coeff_Cleanup(romdata_coeff); XLAL_ERROR(XLAL_EFUNC, "Waveform allocation failed."); } memset((*hptilde)->data->data, 0, npts * sizeof(COMPLEX16)); memset((*hctilde)->data->data, 0, npts * sizeof(COMPLEX16)); XLALUnitMultiply(&(*hptilde)->sampleUnits, &(*hptilde)->sampleUnits, &lalSecondUnit); XLALUnitMultiply(&(*hctilde)->sampleUnits, &(*hctilde)->sampleUnits, &lalSecondUnit); COMPLEX16 *pdata=(*hptilde)->data->data; COMPLEX16 *cdata=(*hctilde)->data->data; REAL8 cosi = cos(inclination); REAL8 pcoef = 0.5*(1.0 + cosi*cosi); REAL8 ccoef = cosi; REAL8 s = 1.0/sqrt(2.0); // Scale polarization amplitude so that strain agrees with FFT of SEOBNRv1 double Mtot = Mtot_sec / LAL_MTSUN_SI; double amp0 = Mtot * amp_pre * Mtot_sec * LAL_MRSUN_SI / (distance); // Correct overall amplitude to undo mass-dependent scaling used in single-spin ROM // Evaluate reference phase for setting phiRef correctly double phase_change = gsl_spline_eval(spline_phi, fRef_geom, acc_phi) - 2*phiRef; // Assemble waveform from aplitude and phase for (UINT4 i=0; i<freqs->length; i++) { // loop over frequency points in sequence double f = freqs->data[i]; if (f > Mf_ROM_max) continue; // We're beyond the highest allowed frequency; since freqs may not be ordered, we'll just skip the current frequency and leave zero in the buffer int j = i + offset; // shift index for frequency series if needed double A = gsl_spline_eval(spline_amp, f, acc_amp); double phase = gsl_spline_eval(spline_phi, f, acc_phi) - phase_change; COMPLEX16 htilde = s*amp0*A * cexp(I*phase); pdata[j] = pcoef * htilde; cdata[j] = -I * ccoef * htilde; } /* Correct phasing so we coalesce at t=0 (with the definition of the epoch=-1/deltaF above) */ // Get SEOBNRv1 ringdown frequency for 22 mode double Mf_final = SEOBNRROM_Ringdown_Mf_From_Mtot_q(Mtot_sec, q, chi, chi, SEOBNRv1); UINT4 L = freqs->length; // prevent gsl interpolation errors if (Mf_final > freqs->data[L-1]) Mf_final = freqs->data[L-1]; if (Mf_final < freqs->data[0]) { XLALDestroyREAL8Sequence(freqs); gsl_spline_free(spline_amp); gsl_spline_free(spline_phi); gsl_interp_accel_free(acc_amp); gsl_interp_accel_free(acc_phi); gsl_vector_free(amp_f); gsl_vector_free(phi_f); SEOBNRROMdata_coeff_Cleanup(romdata_coeff); XLAL_ERROR(XLAL_EDOM, "f_ringdown < f_min"); } // Time correction is t(f_final) = 1/(2pi) dphi/df (f_final) // We compute the dimensionless time correction t/M since we use geometric units. REAL8 t_corr = gsl_spline_eval_deriv(spline_phi, Mf_final, acc_phi) / (2*LAL_PI); // Now correct phase for (UINT4 i=0; i<freqs->length; i++) { // loop over frequency points in sequence double f = freqs->data[i] - fRef_geom; int j = i + offset; // shift index for frequency series if needed pdata[j] *= cexp(-2*LAL_PI * I * f * t_corr); cdata[j] *= cexp(-2*LAL_PI * I * f * t_corr); } XLALDestroyREAL8Sequence(freqs); gsl_spline_free(spline_amp); gsl_spline_free(spline_phi); gsl_interp_accel_free(acc_amp); gsl_interp_accel_free(acc_phi); gsl_vector_free(amp_f); gsl_vector_free(phi_f); SEOBNRROMdata_coeff_Cleanup(romdata_coeff); return(XLAL_SUCCESS); }
/* * Core function for computing the ROM waveform. * Evaluates projection coefficients and shifts in time and phase at desired q. * Construct 1D splines for amplitude and phase. * Compute strain waveform from amplitude and phase. */ static INT4 EOBNRv2HMROMCore( COMPLEX16FrequencySeries **hptilde, COMPLEX16FrequencySeries **hctilde, REAL8 phiRef, REAL8 deltaF, REAL8 fLow, REAL8 fHigh, REAL8 fRef, REAL8 distance, REAL8 inclination, REAL8 Mtot_sec, REAL8 q) { INT4 ret = XLAL_SUCCESS; INT4 i; INT4 j; double tpeak22estimate = 0.; /* Check output arrays */ if(!hptilde || !hctilde) XLAL_ERROR(XLAL_EFAULT); if(*hptilde || *hctilde) { XLALPrintError("(*hptilde) and (*hctilde) are supposed to be NULL, but got %p and %p\n",(*hptilde),(*hctilde)); XLAL_ERROR(XLAL_EFAULT); } /* Check if the data has been set up */ if(__lalsim_EOBNRv2HMROM_setup) { XLALPrintError("Error: the ROM data has not been set up\n"); XLAL_ERROR(XLAL_EFAULT); } /* Set the global pointers to data */ ListmodesEOBNRHMROMdata* listdata = *__lalsim_EOBNRv2HMROM_data; ListmodesEOBNRHMROMdata_interp* listdata_interp = *__lalsim_EOBNRv2HMROM_interp; /* Global amplitude prefactor - includes total mass scaling, Fourier scaling, distance scaling, and undoing an additional arbitrary scaling */ REAL8 Mtot_msol = Mtot_sec / LAL_MTSUN_SI; /* Mtot_msol and M_ROM in units of solar mass */ REAL8 amp0 = (Mtot_msol/M_ROM) * Mtot_sec * 1.E-16 * 1.E6 * LAL_PC_SI / distance; /* Highest allowed geometric frequency for the first mode of listmode in the ROM - used for fRef * by convention, we use the first mode of listmode (presumably the 22) for phiref */ ListmodesEOBNRHMROMdata* listdata_ref = ListmodesEOBNRHMROMdata_GetMode(listdata, listmode[0][0], listmode[0][1]); EOBNRHMROMdata* data_ref = listdata_ref->data; REAL8 Mf_ROM_max_ref = gsl_vector_get(data_ref->freq, nbfreq-1); /* Convert to geometric units for frequency */ REAL8 fLow_geom = fLow * Mtot_sec; REAL8 fHigh_geom = fHigh * Mtot_sec; REAL8 fRef_geom = fRef * Mtot_sec; REAL8 deltaF_geom = deltaF * Mtot_sec; /* Enforce allowed geometric frequency range */ if (fLow_geom < Mf_ROM_min) { /* Enforce minimal frequency */ XLALPrintWarning("Starting frequency Mflow=%g is smaller than lowest frequency in ROM Mf=%g. Starting at lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min); fLow_geom = Mf_ROM_min; } /* Default highest frequency */ if (fHigh == 0) fHigh_geom = Mf_ROM_max; /* In case the user asks for a frequency higher than covered by the ROM, we keep it that way as we will just 0-pad the waveform (and do it anyway for some modes) */ if (fRef_geom > Mf_ROM_max_ref || fRef_geom == 0) fRef_geom = Mf_ROM_max_ref; /* If fRef > fhigh or 0 we reset fRef to default value of cutoff frequency for the first mode of the list (presumably the 22 mode) */ if (0 < fRef_geom && fRef_geom < Mf_ROM_min) { XLALPrintWarning("Reference frequency Mf_ref=%g is smaller than lowest frequency in ROM Mf=%g. Setting it to the lowest frequency in ROM.\n", fLow_geom, Mf_ROM_min); fRef_geom = Mf_ROM_min; } /* Set up output array with size closest power of 2 - fHigh is the upper frequency specified by the user */ size_t nbpt = NextPow2(fHigh_geom / deltaF_geom) + 1; /* Internal storage for the projection coefficients and shifts in time and phase */ /* Initialized only once, and reused for the different modes */ EOBNRHMROMdata_coeff *data_coeff = NULL; EOBNRHMROMdata_coeff_Init(&data_coeff); /* Create spherical harmonic frequency series that will contain the hlm's */ SphHarmFrequencySeries** hlmsphharmfreqseries = XLALMalloc(sizeof(SphHarmFrequencySeries)); *hlmsphharmfreqseries = NULL; /* GPS time definition - common to all modes */ LIGOTimeGPS tC; XLALGPSAdd(&tC, -1. / deltaF); /* coalesce at t=0 */ /* The phase change imposed by phiref, from the phase of the first mode in the list - to be set in the first step of the loop on the modes */ REAL8 phase_change_ref = 0; /* Main loop over the modes */ for( i=0; i<nbmode; i++ ){ UINT4 l = listmode[i][0]; INT4 m = listmode[i][1]; /* Getting the relevant modes in the lists of data */ ListmodesEOBNRHMROMdata* listdata_mode = ListmodesEOBNRHMROMdata_GetMode(listdata, l, m); ListmodesEOBNRHMROMdata_interp* listdata_interp_mode = ListmodesEOBNRHMROMdata_interp_GetMode(listdata_interp, l, m); /* Evaluating the projection coefficients and shift in time and phase */ ret |= Evaluate_Spline_Data(q, listdata_interp_mode->data_interp, data_coeff); /* Evaluating the unnormalized amplitude and unshifted phase vectors for the mode */ /* Notice a change in convention: B matrices are transposed with respect to the B matrices in SEOBNRROM */ /* amp_pts = Bamp . Camp_coeff */ /* phi_pts = Bphi . Cphi_coeff */ gsl_vector* amp_f = gsl_vector_alloc(nbfreq); gsl_vector* phi_f = gsl_vector_alloc(nbfreq); gsl_blas_dgemv(CblasNoTrans, 1.0, listdata_mode->data->Bamp, data_coeff->Camp_coeff, 0.0, amp_f); gsl_blas_dgemv(CblasNoTrans, 1.0, listdata_mode->data->Bphi, data_coeff->Cphi_coeff, 0.0, phi_f); /* The downsampled frequencies for the mode - we undo the rescaling of the frequency for the 44 and 55 modes */ gsl_vector* freq_ds = gsl_vector_alloc(nbfreq); gsl_vector_memcpy(freq_ds, listdata_mode->data->freq); if ( l==4 && m==4) gsl_vector_scale( freq_ds, 1./Scaling44(q)); if ( l==5 && m==5) gsl_vector_scale( freq_ds, 1./Scaling55(q)); /* Evaluating the shifts in time and phase - conditional scaling for the 44 and 55 modes */ /* Note: the stored values of 'shifttime' correspond actually to 2pi*Deltat */ SplineList* shifttime_splinelist = listdata_interp_mode->data_interp->shifttime_interp; SplineList* shiftphase_splinelist = listdata_interp_mode->data_interp->shiftphase_interp; REAL8 twopishifttime; if( l==4 && m==4) { twopishifttime = gsl_spline_eval(shifttime_splinelist->spline, q, shifttime_splinelist->accel) * Scaling44(q); } else if( l==5 && m==5) { twopishifttime = gsl_spline_eval(shifttime_splinelist->spline, q, shifttime_splinelist->accel) * Scaling55(q); } else { twopishifttime = gsl_spline_eval(shifttime_splinelist->spline, q, shifttime_splinelist->accel); } REAL8 shiftphase = gsl_spline_eval(shiftphase_splinelist->spline, q, shiftphase_splinelist->accel); /* If first mode in the list, assumed to be the 22 mode, set totalshifttime and phase_change_ref */ if( i==0 ) { if(l==2 && m==2) { /* Setup 1d cubic spline for the phase of the 22 mode */ gsl_interp_accel* accel_phi22 = gsl_interp_accel_alloc(); gsl_spline* spline_phi22 = gsl_spline_alloc(gsl_interp_cspline, nbfreq); gsl_spline_init(spline_phi22, gsl_vector_const_ptr(freq_ds,0), gsl_vector_const_ptr(phi_f,0), nbfreq); /* Compute the shift in time needed to set the peak of the 22 mode roughly at t=0 */ /* We use the SPA formula tf = -(1/2pi)*dPsi/df to estimate the correspondence between frequency and time */ /* The frequency corresponding to the 22 peak is omega22peak/2pi, with omega22peak taken from the fit to NR in Pan&al 1106 EOBNRv2HM paper */ double f22peak = fmin(omega22peakOfq(q)/(2*LAL_PI), Mf_ROM_max_ref); /* We ensure we evaluate the spline within its range */ tpeak22estimate = -1./(2*LAL_PI) * gsl_spline_eval_deriv(spline_phi22, f22peak, accel_phi22); /* Determine the change in phase (to be propagated to all modes) required to have phi22(fRef) = 2*phiRef */ phase_change_ref = 2*phiRef + (gsl_spline_eval(spline_phi22, fRef_geom, accel_phi22) - (twopishifttime - 2*LAL_PI*tpeak22estimate) * fRef_geom - shiftphase); gsl_spline_free(spline_phi22); gsl_interp_accel_free(accel_phi22); } else { XLALPrintError("Error: the first mode in listmode must be the 22 mode to set the changes in phase and time \n"); XLAL_ERROR(XLAL_EFAILED); } } /* Total shift in time, and total change in phase for this mode */ double totaltwopishifttime = twopishifttime - 2*LAL_PI*tpeak22estimate; double constphaseshift = (double) m/listmode[0][1] * phase_change_ref + shiftphase; /* Initialize the complex series for the mode - notice that metadata used here is useless, only the one for the final output will matter */ COMPLEX16FrequencySeries* mode = XLALCreateCOMPLEX16FrequencySeries("mode hlm", &tC, 0.0, deltaF, &lalStrainUnit, nbpt); memset(mode->data->data, 0, nbpt * sizeof(COMPLEX16)); /* Setup 1d cubic spline for the phase and amplitude of the mode */ gsl_interp_accel* accel_phi = gsl_interp_accel_alloc(); gsl_interp_accel* accel_amp = gsl_interp_accel_alloc(); gsl_spline* spline_phi = gsl_spline_alloc(gsl_interp_cspline, nbfreq); gsl_spline* spline_amp = gsl_spline_alloc(gsl_interp_cspline, nbfreq); gsl_spline_init(spline_phi, gsl_vector_const_ptr(freq_ds,0), gsl_vector_const_ptr(phi_f,0), nbfreq); gsl_spline_init(spline_amp, gsl_vector_const_ptr(freq_ds,0), gsl_vector_const_ptr(amp_f,0), nbfreq); /* Interval in frequency covered by the ROM */ REAL8 fLow_geom_mode = gsl_vector_get(freq_ds, 0); REAL8 fHigh_geom_mode = fmin(gsl_vector_get(freq_ds, nbfreq-1), fHigh_geom); /* Initialize the loop - values outside this range in j are 0 by default */ INT4 jStart = (UINT4) ceil(fLow_geom_mode / deltaF_geom); INT4 jStop = (UINT4) ceil(fHigh_geom_mode / deltaF_geom); COMPLEX16 *modedata = mode->data->data; /* Mode-dependent complete amplitude prefactor */ REAL8 amp_pre = amp0 * ModeAmpFactor( l, m, q); /* Loop on the frequency samples chosen to evaluate the waveform */ /* We set apart the first and last step to avoid falling outside of the range of the splines by numerical errors */ REAL8 f, A, phase; f = fmax(fLow_geom_mode, jStart*deltaF_geom); A = gsl_spline_eval(spline_amp, f, accel_amp); phase = -gsl_spline_eval(spline_phi, f, accel_phi) + totaltwopishifttime * f + constphaseshift; /* Minus sign put here, in the internals of the ROM model \Psi = -phase */ modedata[jStart] = amp_pre * A * cexp(I*phase); for (j=jStart+1; j<jStop-1; j++) { f = j*deltaF_geom; A = gsl_spline_eval(spline_amp, f, accel_amp); phase = -gsl_spline_eval(spline_phi, f, accel_phi) + totaltwopishifttime * f + constphaseshift; /* Minus sign put here, in the internals of the ROM model \Psi = -phase */ modedata[j] = amp_pre * A * cexp(I*phase); } f = fmin(fHigh_geom_mode, (jStop-1)*deltaF_geom); A = gsl_spline_eval(spline_amp, f, accel_amp); phase = -gsl_spline_eval(spline_phi, f, accel_phi) + totaltwopishifttime * f + constphaseshift; /* Minus sign put here, in the internals of the ROM model \Psi = -phase */ modedata[jStop-1] = amp_pre * A * cexp(I*phase); /* Add the computed mode to the SphHarmFrequencySeries structure */ *hlmsphharmfreqseries = XLALSphHarmFrequencySeriesAddMode(*hlmsphharmfreqseries, mode, l, m); /* Cleanup for the mode */ gsl_spline_free(spline_amp); gsl_spline_free(spline_phi); gsl_interp_accel_free(accel_amp); gsl_interp_accel_free(accel_phi); gsl_vector_free(amp_f); gsl_vector_free(phi_f); gsl_vector_free(freq_ds); XLALDestroyCOMPLEX16FrequencySeries(mode); } /* Cleanup of the coefficients data structure */ EOBNRHMROMdata_coeff_Cleanup(data_coeff); /* Combining the modes for a hplus, hcross output */ /* Initialize the complex series hplus, hcross */ *hptilde = XLALCreateCOMPLEX16FrequencySeries("hptilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, nbpt); *hctilde = XLALCreateCOMPLEX16FrequencySeries("hctilde: FD waveform", &tC, 0.0, deltaF, &lalStrainUnit, nbpt); if (!(hptilde) || !(*hctilde)) XLAL_ERROR(XLAL_EFUNC); memset((*hptilde)->data->data, 0, nbpt * sizeof(COMPLEX16)); memset((*hctilde)->data->data, 0, nbpt * sizeof(COMPLEX16)); XLALUnitDivide(&(*hptilde)->sampleUnits, &(*hptilde)->sampleUnits, &lalSecondUnit); XLALUnitDivide(&(*hctilde)->sampleUnits, &(*hctilde)->sampleUnits, &lalSecondUnit); /* Adding the modes to form hplus, hcross * - use of a function that copies XLALSimAddMode but for Fourier domain structures */ INT4 sym; /* sym will decide whether to add the -m mode (when equatorial symmetry is present) */ for( i=0; i<nbmode; i++){ INT4 l = listmode[i][0]; INT4 m = listmode[i][1]; COMPLEX16FrequencySeries* mode = XLALSphHarmFrequencySeriesGetMode(*hlmsphharmfreqseries, l, m); if ( m==0 ) sym = 0; /* We test for hypothetical m=0 modes */ else sym = 1; FDAddMode( *hptilde, *hctilde, mode, inclination, 0., l, m, sym); /* The phase \Phi is set to 0 - assumes phiRef is defined as half the phase of the 22 mode h22 (or the first mode in the list), not for h = hplus-I hcross */ } /* Destroying the list of frequency series for the modes, including the COMPLEX16FrequencySeries that it contains */ XLALDestroySphHarmFrequencySeries(*hlmsphharmfreqseries); XLALFree(hlmsphharmfreqseries); /* Additional complex conjugation of hptilde, hctilde - due to the difference in convention for the Fourier transform between LAL and the ROM internals */ COMPLEX16* datap = (*hptilde)->data->data; COMPLEX16* datac = (*hctilde)->data->data; for ( j = 0; j < (INT4) (*hptilde)->data->length; ++j ) { datap[j] = conj(datap[j]); } for ( j = 0; j < (INT4) (*hctilde)->data->length; ++j ) { datac[j] = conj(datac[j]); } return(XLAL_SUCCESS); }
/* Function interpolating the data in matrix/vector form produces an interpolated data in the form of SplineLists */ static INT4 Interpolate_Spline_Data(const EOBNRHMROMdata *data, EOBNRHMROMdata_interp *data_interp) { gsl_set_error_handler(&err_handler); SplineList* splinelist; gsl_spline* spline; gsl_interp_accel* accel; gsl_vector* matrixline; gsl_vector* vector; INT4 j; /* Interpolating Camp */ splinelist = data_interp->Camp_interp; for (j = 0; j<nk_amp; j++) { matrixline = gsl_vector_alloc(nbwf); gsl_matrix_get_row(matrixline, data->Camp, j); accel = gsl_interp_accel_alloc(); spline = gsl_spline_alloc(gsl_interp_cspline, nbwf); gsl_spline_init(spline, gsl_vector_const_ptr(data->q, 0), gsl_vector_const_ptr(matrixline, 0), nbwf); splinelist = SplineList_AddElementNoCopy(splinelist, spline, accel, j); gsl_vector_free(matrixline); } data_interp->Camp_interp = splinelist; /* Interpolating Cphi */ splinelist = data_interp->Cphi_interp; for (j = 0; j<nk_phi; j++) { matrixline = gsl_vector_alloc(nbwf); gsl_matrix_get_row(matrixline, data->Cphi, j); accel = gsl_interp_accel_alloc(); spline = gsl_spline_alloc(gsl_interp_cspline, nbwf); gsl_spline_init(spline, gsl_vector_const_ptr(data->q, 0), gsl_vector_const_ptr(matrixline, 0), nbwf); splinelist = SplineList_AddElementNoCopy(splinelist, spline, accel, j); gsl_vector_free(matrixline); } data_interp->Cphi_interp = splinelist; /* Interpolating shifttime */ splinelist = data_interp->shifttime_interp; vector = data->shifttime; accel = gsl_interp_accel_alloc(); spline = gsl_spline_alloc(gsl_interp_cspline, nbwf); gsl_spline_init(spline, gsl_vector_const_ptr(data->q, 0), gsl_vector_const_ptr(vector, 0), nbwf); splinelist = SplineList_AddElementNoCopy(NULL, spline, accel, 0); /* This SplineList has only 1 element */ data_interp->shifttime_interp = splinelist; /* Interpolating shiftphase */ splinelist = data_interp->shiftphase_interp; vector = data->shiftphase; accel = gsl_interp_accel_alloc(); spline = gsl_spline_alloc(gsl_interp_cspline, nbwf); gsl_spline_init(spline, gsl_vector_const_ptr(data->q, 0), gsl_vector_const_ptr(vector, 0), nbwf); splinelist = SplineList_AddElementNoCopy(NULL, spline, accel, 0); /* This SplineList has only 1 element */ data_interp->shiftphase_interp = splinelist; return XLAL_SUCCESS; }
static int psi_func(const gsl_vector *x, void *params, gsl_vector *f) { HklVector dhkl0, hkl1; HklVector ki, kf, Q, n; HklMatrix RUB; HklPseudoAxisEngine *engine; HklPseudoAxisEngineModePsi *modepsi; HklPseudoAxis *psi; HklHolder *holder; size_t i; size_t len; double const *x_data = gsl_vector_const_ptr(x, 0); double *f_data = gsl_vector_ptr(f, 0); engine = params; modepsi = (HklPseudoAxisEngineModePsi *)engine->mode; psi = engine->pseudoAxes[0]; /* update the workspace from x; */ len = HKL_LIST_LEN(engine->axes); for(i=0; i<len; ++i) hkl_axis_set_value(engine->axes[i], x_data[i]); hkl_geometry_update(engine->geometry); /* kf - ki = Q */ hkl_source_compute_ki(&engine->geometry->source, &ki); hkl_detector_compute_kf(engine->detector, engine->geometry, &kf); Q = kf; hkl_vector_minus_vector(&Q, &ki); if (hkl_vector_is_null(&Q)){ f_data[0] = 1; f_data[1] = 1; f_data[2] = 1; f_data[3] = 1; }else{ /* R * UB */ /* for now the 0 holder is the sample holder. */ holder = &engine->geometry->holders[0]; hkl_quaternion_to_matrix(&holder->q, &RUB); hkl_matrix_times_matrix(&RUB, &engine->sample->UB); /* compute dhkl0 */ hkl_matrix_solve(&RUB, &dhkl0, &Q); hkl_vector_minus_vector(&dhkl0, &modepsi->hkl0); /* compute the intersection of the plan P(kf, ki) and PQ (normal Q) */ /* * now that dhkl0 have been computed we can use a * normalized Q to compute n and psi */ hkl_vector_normalize(&Q); n = kf; hkl_vector_vectorial_product(&n, &ki); hkl_vector_vectorial_product(&n, &Q); /* compute hkl1 in the laboratory referentiel */ /* for now the 0 holder is the sample holder. */ hkl1.data[0] = engine->mode->parameters[0].value; hkl1.data[1] = engine->mode->parameters[1].value; hkl1.data[2] = engine->mode->parameters[2].value; hkl_vector_times_matrix(&hkl1, &engine->sample->UB); hkl_vector_rotated_quaternion(&hkl1, &engine->geometry->holders[0].q); /* project hkl1 on the plan of normal Q */ hkl_vector_project_on_plan(&hkl1, &Q); if (hkl_vector_is_null(&hkl1)){ /* hkl1 colinear with Q */ f_data[0] = dhkl0.data[0]; f_data[1] = dhkl0.data[1]; f_data[2] = dhkl0.data[2]; f_data[3] = 1; }else{ f_data[0] = dhkl0.data[0]; f_data[1] = dhkl0.data[1]; f_data[2] = dhkl0.data[2]; f_data[3] = psi->parent.value - hkl_vector_oriented_angle(&n, &hkl1, &Q); } } return GSL_SUCCESS; }
/* Function loading the noise data from a directory */ int LLVSimFD_Noise_Init(const char dir[]) { if(!__LLVSimFD_Noise_setup) { printf("Error: LLVSimFD noise was already set up!"); exit(1); } /* Loading noise data in gsl_vectors */ int ret = SUCCESS; gsl_matrix* noise_LHO = gsl_matrix_alloc(noisedata_pts, 2); gsl_matrix* noise_LLO = gsl_matrix_alloc(noisedata_pts, 2); gsl_matrix* noise_VIRGO = gsl_matrix_alloc(noisedata_pts, 2); char* file_LIGO = malloc(strlen(dir)+64); char* file_VIRGO = malloc(strlen(dir)+64); //sprintf(file_LIGO, "%s", "LIGO-P1200087-v18-aLIGO_DESIGN.txt"); //sprintf(file_VIRGO, "%s", "LIGO-P1200087-v18-AdV_DESIGN.txt"); sprintf(file_LIGO, "%s", "aLIGO_sensitivity.dat"); sprintf(file_VIRGO, "%s", "aVirgo_sensitivity.dat"); ret |= Read_Text_Matrix(dir, file_LIGO, noise_LHO); ret |= Read_Text_Matrix(dir, file_LIGO, noise_LLO); ret |= Read_Text_Matrix(dir, file_VIRGO, noise_VIRGO); if(ret==FAILURE) { printf("Error: problem reading LLV noise data."); exit(1); } /* Linear interpolation of the data, after setting the gsl_spline structures */ else if(ret==SUCCESS) { /* Extracting te vectors for the frequencies and data */ gsl_vector* noise_LHO_freq = gsl_vector_alloc(noisedata_pts); gsl_vector* noise_LLO_freq = gsl_vector_alloc(noisedata_pts); gsl_vector* noise_VIRGO_freq = gsl_vector_alloc(noisedata_pts); gsl_vector* noise_LHO_data = gsl_vector_alloc(noisedata_pts); gsl_vector* noise_LLO_data = gsl_vector_alloc(noisedata_pts); gsl_vector* noise_VIRGO_data = gsl_vector_alloc(noisedata_pts); gsl_matrix_get_col(noise_LHO_freq, noise_LHO, 0); gsl_matrix_get_col(noise_LLO_freq, noise_LLO, 0); gsl_matrix_get_col(noise_VIRGO_freq, noise_VIRGO, 0); gsl_matrix_get_col(noise_LHO_data, noise_LHO, 1); gsl_matrix_get_col(noise_LLO_data, noise_LLO, 1); gsl_matrix_get_col(noise_VIRGO_data, noise_VIRGO, 1); /* Setting the global variables that indicate the range in frequency of these splines */ __LLVSimFD_LHONoise_fLow = gsl_vector_get(noise_LHO_freq, 0); __LLVSimFD_LHONoise_fHigh = gsl_vector_get(noise_LHO_freq, noise_LHO_freq->size - 1); __LLVSimFD_LLONoise_fLow = gsl_vector_get(noise_LLO_freq, 0); __LLVSimFD_LLONoise_fHigh = gsl_vector_get(noise_LLO_freq, noise_LLO_freq->size - 1); __LLVSimFD_VIRGONoise_fLow = gsl_vector_get(noise_VIRGO_freq, 0); __LLVSimFD_VIRGONoise_fHigh = gsl_vector_get(noise_VIRGO_freq, noise_VIRGO_freq->size - 1); /* Initializing the splines and accelerators */ *__LLVSimFD_LHONoiseSpline = gsl_spline_alloc(gsl_interp_linear, noisedata_pts); *__LLVSimFD_LLONoiseSpline = gsl_spline_alloc(gsl_interp_linear, noisedata_pts); *__LLVSimFD_VIRGONoiseSpline = gsl_spline_alloc(gsl_interp_linear, noisedata_pts); *__LLVSimFD_LHONoiseAccel = gsl_interp_accel_alloc(); *__LLVSimFD_LLONoiseAccel = gsl_interp_accel_alloc(); *__LLVSimFD_VIRGONoiseAccel = gsl_interp_accel_alloc(); gsl_spline_init(*__LLVSimFD_LHONoiseSpline, gsl_vector_const_ptr(noise_LHO_freq, 0), gsl_vector_const_ptr(noise_LHO_data, 0), noisedata_pts); gsl_spline_init(*__LLVSimFD_LLONoiseSpline, gsl_vector_const_ptr(noise_LLO_freq, 0), gsl_vector_const_ptr(noise_LLO_data, 0), noisedata_pts); gsl_spline_init(*__LLVSimFD_VIRGONoiseSpline, gsl_vector_const_ptr(noise_VIRGO_freq, 0), gsl_vector_const_ptr(noise_VIRGO_data, 0), noisedata_pts); /* Setting the global tag to success and clean up */ gsl_matrix_free(noise_LHO); gsl_matrix_free(noise_LLO); gsl_matrix_free(noise_VIRGO); gsl_vector_free(noise_LHO_freq); gsl_vector_free(noise_LLO_freq); gsl_vector_free(noise_VIRGO_freq); gsl_vector_free(noise_LHO_data); gsl_vector_free(noise_LLO_data); gsl_vector_free(noise_VIRGO_data); __LLVSimFD_Noise_setup = SUCCESS; } /* Cleaning and output */ free(file_LIGO); free(file_VIRGO); return(ret); }