def compute_modulus(paramspoint, known_bases, distance, deltaF, f_min, f_max, approximant): waveFlags = lal.CreateDict() m1, m2 = get_m1m2_from_mcq(paramspoint[0], paramspoint[1]) s1x, s1y, s1z = spherical_to_cartesian(paramspoint[2:5]) s2x, s2y, s2z = spherical_to_cartesian(paramspoint[5:8]) iota = paramspoint[8] phiRef = paramspoint[9] ecc = 0 if len(paramspoint) == 11: ecc = paramspoint[10] if len(paramspoint) == 12: lambda1 = paramspoint[10] lambda2 = paramspoint[11] lalsimulation.SimInspiralWaveformParamsInsertTidalLambda1( waveFlags, lambda1) lalsimulation.SimInspiralWaveformParamsInsertTidalLambda2( waveFlags, lambda2) f_ref = 0 RA = 0 DEC = 0 psi = 0 phi = 0 m1 *= lal.lal.MSUN_SI m2 *= lal.lal.MSUN_SI [plus, cross] = lalsimulation.SimInspiralChooseFDWaveform( m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, distance, iota, phiRef, 0, ecc, 0, deltaF, f_min, f_max, f_ref, waveFlags, approximant) hp_tmp = plus.data.data[numpy.int(f_min / deltaF):numpy.int( f_max / deltaF)] # data_tmp is hplus and is a complex vector residual = hp_tmp for k in numpy.arange(0, len(known_bases)): residual -= proj(known_bases[k], hp_tmp) modulus = numpy.sqrt(numpy.vdot(residual, residual)) return modulus
def _eval_fit(self, fit_params, fit_type, extra_params_dict): """ Evaluates a particular fit for NRSur3dq8Remnant using the fit_params returned by _get_fit_params(). """ q, chiAz, chiBz = fit_params LALParams = lal.CreateDict() if extra_params_dict["unlimited_extrapolation"]: lal.DictInsertUINT4Value(LALParams, "unlimited_extrapolation", 1) if fit_type == "FinalMass": # FinalMass is given as a fraction of total mass val = lalsim.NRSur3dq8Remnant(q, chiAz, chiBz, "mf", LALParams) elif fit_type == "FinalSpin": # chifx and chify are zero for aligned-spin systems chifz = lalsim.NRSur3dq8Remnant(q, chiAz, chiBz, "chifz", LALParams) val = [0,0,chifz] elif fit_type == "RecoilKick": # vfz is zero for aligned-spin systems vfx = lalsim.NRSur3dq8Remnant(q, chiAz, chiBz, "vfx", LALParams) vfy = lalsim.NRSur3dq8Remnant(q, chiAz, chiBz, "vfy", LALParams) val = [vfx, vfy, 0] else: raise ValueError("Invalid fit_type=%s. This model only allows " "'FinalMass', 'FinalSpin' and 'RecoilKick'."%fit_type) return np.atleast_1d(val)
def _lalsim_fd_waveform(**p): lal_pars = lal.CreateDict() if p['phase_order'] != -1: lalsimulation.SimInspiralWaveformParamsInsertPNPhaseOrder( lal_pars, int(p['phase_order'])) if p['amplitude_order'] != -1: lalsimulation.SimInspiralWaveformParamsInsertPNAmplitudeOrder( lal_pars, int(p['amplitude_order'])) if p['spin_order'] != -1: lalsimulation.SimInspiralWaveformParamsInsertPNSpinOrder( lal_pars, int(p['spin_order'])) if p['tidal_order'] != -1: lalsimulation.SimInspiralWaveformParamsInsertPNTidalOrder( lal_pars, p['tidal_order']) if p['eccentricity_order'] != -1: lalsimulation.SimInspiralWaveformParamsInsertPNEccentricityOrder( lal_pars, p['eccentricity_order']) if p['lambda1']: lalsimulation.SimInspiralWaveformParamsInsertPNTidalLambda1( lal_pars, p['lambda1']) if p['lambda2']: lalsimulation.SimInspiralWaveformParamsInsertPNTidalLambda2( lal_pars, p['lambda2']) if p['dquad_mon1']: lalsimulation.SimInspiralWaveformParamsInsertPNTidaldQuadMon1( lal_pars, p['dquad_mon1']) if p['dquad_mon2']: lalsimulation.SimInspiralWaveformParamsInsertPNTidaldQuadMon2( lal_pars, p['dquad_mon2']) if p['numrel_data']: lalsimulation.SimInspiralWaveformParamsInsertNumRelData( lal_pars, str(p['numrel_data'])) if p['modes_choice']: lalsimulation.SimInspiralWaveformParamsInsertModesChoice( lal_pars, p['modes_choice']) if p['frame_axis']: lalsimulation.SimInspiralWaveformParamsInsertFrameAxis( lal_pars, p['frame_axis']) if p['side_bands']: lalsimulation.SimInspiralWaveformParamsInsertSideband( lal_pars, p['side_bands']) #nonGRparams can be straightforwardly added if needed, however they have to # be invoked one by one hp1, hc1 = lalsimulation.SimInspiralChooseFDWaveform( float(pnutils.solar_mass_to_kg(p['mass1'])), float(pnutils.solar_mass_to_kg(p['mass2'])), float(p['spin1x']), float(p['spin1y']), float(p['spin1z']), float(p['spin2x']), float(p['spin2y']), float(p['spin2z']), pnutils.megaparsecs_to_meters(float(p['distance'])), float(p['inclination']), float(p['coa_phase']), float(p['long_asc_nodes']), float(p['eccentricity']), float(p['mean_per_ano']), p['delta_f'], float(p['f_lower']), float(p['f_final']), float(p['f_ref']), lal_pars, _lalsim_enum[p['approximant']]) hp = FrequencySeries(hp1.data.data[:], delta_f=hp1.deltaF, epoch=hp1.epoch) hc = FrequencySeries(hc1.data.data[:], delta_f=hc1.deltaF, epoch=hc1.epoch) #lal.DestroyDict(lal_pars) return hp, hc
def spin_tidal_IMRPhenomD_FD(m1, m2, s1z, s2z, lambda1, lambda2, f_min, f_max, deltaF=1.0/128.0, delta_t=1.0/16384.0, distance=1.0, inclination=0.0, approximant='IMRPhenomD_NRTidal', verbose=True): # print m1, m2, s1z, s2z, lambda1, lambda2, f_min, delta_t, distance, inclination f_ref = 0. phiRef = 0. # Must have aligned spin s1x, s1y, s2x, s2y = 0., 0., 0., 0. # Eccentricity is not part of the model longAscNodes = 0. eccentricity = 0. meanPerAno = 0. lal_approx = LS.GetApproximantFromString(approximant) # Insert matter parameters lal_params = lal.CreateDict() LS.SimInspiralWaveformParamsInsertTidalLambda1(lal_params, lambda1) LS.SimInspiralWaveformParamsInsertTidalLambda2(lal_params, lambda2) # Evaluate FD waveform Hp, Hc = LS.SimInspiralFD( m1*lal.MSUN_SI, m2*lal.MSUN_SI, s1x, s1y, s1z, s2x, s2y, s2z, distance*lal.PC_SI, inclination, phiRef, longAscNodes, eccentricity, meanPerAno, deltaF, f_min, f_max, f_ref, lal_params, lal_approx) f = deltaF * np.arange(Hp.data.length) return f, Hp, Hc
def generate_LAL_modes(approximant, q, chiA0, chiB0, dt, M, \ dist_mpc, f_low, f_ref, phi_ref, ellMax=None): distance = dist_mpc * 1.0e6 * PC_SI approxTag = lalsim.SimInspiralGetApproximantFromString(approximant) # component masses of the binary m1_kg = M * MSUN_SI * q / (1. + q) m2_kg = M * MSUN_SI / (1. + q) dictParams = lal.CreateDict() if ellMax is not None: ma = lalsim.SimInspiralCreateModeArray() for ell in range(2, ellMax + 1): lalsim.SimInspiralModeArrayActivateAllModesAtL(ma, ell) lalsim.SimInspiralWaveformParamsInsertModeArray(dictParams, ma) lmax = 5 # This in unused hmodes = lalsim.SimInspiralChooseTDModes(phi_ref, dt, m1_kg, m2_kg, \ chiA0[0], chiA0[1], chiA0[2], chiB0[0], chiB0[1], chiB0[2], \ f_low, f_ref, distance, dictParams, lmax, approxTag) t = np.arange(len(hmodes.mode.data.data)) * dt mode_dict = {} while hmodes is not None: mode_dict['h_l%dm%d' % (hmodes.l, hmodes.m)] = hmodes.mode.data.data hmodes = hmodes.next return t, mode_dict
def generateWfparameters(opts): '''Turn parameters specified by input file and/or command line options into parameter dictionary that can be used for waveform generation.''' optsDict = vars(opts) inputpar = copy.deepcopy(optsDict) inputpar['m1'] *= lal.MSUN_SI inputpar['m2'] *= lal.MSUN_SI inputpar['distance'] *= (1.e6 * lal.PC_SI) inputpar['approximant'] = lalsim.GetApproximantFromString( inputpar['approximant']) if (inputpar['sampleRate'] != defSampleRate): inputpar['deltaT'] = 1./inputpar['sampleRate'] optsDict['deltaT'] = inputpar['deltaT'] domain = optsDict['domain'] wfinputpar=[inputpar[name] for name in paramnames[domain]] LALpars=lal.CreateDict() if (inputpar['lambda1']): lalsim.SimInspiralWaveformParamsInsertTidalLambda1(LALpars,inputpar['lambda1']) if (inputpar['lambda2']): lalsim.SimInspiralWaveformParamsInsertTidalLambda2(LALpars,inputpar['lambda2']) if (inputpar['ampOrder']!=-1): lalsim.SimInspiralWaveformParamsInsertPNAmplitudeOrder(LALpars,inputpar['ampOrder']) if (inputpar['phaseOrder']!=-1): lalsim.SimInspiralWaveformParamsInsertPNPhaseOrder(LALpars,inputpar['phaseOrder']) wfinputpar.append(LALpars) wfinputpar.append(inputpar['approximant']) return domain, wfinputpar, optsDict
def get_strain(fseries, fref=100): # injection param m1, m2 = 38.90726199927476, 4.099826620277696 m1*=lal.MSUN_SI m2*=lal.MSUN_SI s1x, s1y, s1z = -0.5292121532005147, 0.0815506948762848, 0.6489430710417405 s2x, s2y, s2z = 0.32082521678503834, -0.7843006704918378, 0.02983346070373225 iota = 2.489741666120003 phase = 2.3487991630017353 dist= 100 # convert fseries to lal vector F = fseries F = lal.CreateREAL8Vector(len(F)) F.data[:] = fseries # compute strain WFdict = lal.CreateDict() hplus, hcross = lalsim.SimInspiralChooseFDWaveformSequence( phase, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, fref, dist * 1e6 * lal.PC_SI, iota, WFdict, lalsim.IMRPhenomXPHM, F ) return dict( asd = np.abs(hplus.data.data), phase = np.unwrap(np.angle(hplus.data.data)), time = np.fft.irfft(hplus.data.data) )
def get_SEOBNRv2_WF(q, M, chi1, chi2, f_start, deltaT=1. / (4096 * 4.)): m1 = q * M / (1 + q) m2 = M / (1 + q) hp, hc = lalsim.SimInspiralChooseTDWaveform( #where is its definition and documentation???? m1 * lalsim.lal.MSUN_SI, #m1 m2 * lalsim.lal.MSUN_SI, #m2 0., 0., chi1, #spin vector 1 0., 0., chi2, #spin vector 2 1e6 * lalsim.lal.PC_SI, #distance to source 0., #inclination 0., #phi 0., #longAscNodes 0., #eccentricity 0., #meanPerAno deltaT, # time incremental step f_start, # lowest value of freq f_start, #some reference value of freq (??) lal.CreateDict(), #some lal dictionary lalsim.SimInspiralGetApproximantFromString( 'SpinTaylorT4') #approx method for the model ) h_p, h_c = hp.data.data, hc.data.data times = np.linspace(0, len(h_c) * deltaT, len(h_c)) ph = np.unwrap(np.angle(h_p + 1j * h_c)) omega_22 = (ph[2] - ph[0]) / (2 * deltaT) print("FREQUENCY of THE WF (NP): ", omega_22, omega_22 / (2 * np.pi)) t_max = times[np.argmax(np.abs(h_p + 1j * h_c))] times = times - t_max return times, h_p + 1j * h_c
def gen_test_data(spin1x, approximant, mode_array): """ compute the difference between two waveforms and compare to expected value """ lalparams = lal.CreateDict() if (mode_array != None): ModeArray = lalsimulation.SimInspiralCreateModeArray() for mode in mode_array: lalsimulation.SimInspiralModeArrayActivateMode( ModeArray, mode[0], mode[1]) lalsimulation.SimInspiralWaveformParamsInsertModeArray( lalparams, ModeArray) common_pars = dict(m1=50 * lal.MSUN_SI, m2=30 * lal.MSUN_SI, s1x=spin1x, s1y=0., s1z=0., s2x=0., s2y=0., s2z=0., distance=1, inclination=np.pi / 3., phiRef=0., longAscNodes=0., eccentricity=0., meanPerAno=0., deltaT=1. / 4096., f_min=30., f_ref=30., params=lalparams, approximant=approximant) pars1 = common_pars.copy() pars2 = common_pars.copy() pars2.update({"inclination": 0.17}) pars2.update({"phiRef": 0.5}) hp1, hc1 = lalsimulation.SimInspiralChooseTDWaveform(**pars1) hp2, hc2 = lalsimulation.SimInspiralChooseTDWaveform(**pars2) # compute amp and phase hp1_amp, hp1_phase = get_amp_phase(hp1.data.data) hc1_amp, hc1_phase = get_amp_phase(hc1.data.data) hp2_amp, hp2_phase = get_amp_phase(hp2.data.data) hc2_amp, hc2_phase = get_amp_phase(hc2.data.data) hp_amp_diff = sum_sqr_diff(hp1_amp, hp2_amp) hp_phase_diff = sum_sqr_diff(hp1_phase, hp2_phase) hc_amp_diff = sum_sqr_diff(hc1_amp, hc2_amp) hc_phase_diff = sum_sqr_diff(hc1_phase, hc2_phase) return hp_amp_diff, hp_phase_diff, hc_amp_diff, hc_phase_diff
def _check_lal_pars(p): """ Create a laldict object from the dictionary of waveform parameters Parameters ---------- p: dictionary The dictionary of lalsimulation paramaters Returns ------- laldict: LalDict The lal type dictionary to pass to the lalsimulation waveform functions. """ lal_pars = lal.CreateDict() #nonGRparams can be straightforwardly added if needed, however they have to # be invoked one by one if p['phase_order'] != -1: lalsimulation.SimInspiralWaveformParamsInsertPNPhaseOrder( lal_pars, int(p['phase_order'])) if p['amplitude_order'] != -1: lalsimulation.SimInspiralWaveformParamsInsertPNAmplitudeOrder( lal_pars, int(p['amplitude_order'])) if p['spin_order'] != -1: lalsimulation.SimInspiralWaveformParamsInsertPNSpinOrder( lal_pars, int(p['spin_order'])) if p['tidal_order'] != -1: lalsimulation.SimInspiralWaveformParamsInsertPNTidalOrder( lal_pars, p['tidal_order']) if p['eccentricity_order'] != -1: lalsimulation.SimInspiralWaveformParamsInsertPNEccentricityOrder( lal_pars, p['eccentricity_order']) if p['lambda1']: lalsimulation.SimInspiralWaveformParamsInsertTidalLambda1( lal_pars, p['lambda1']) if p['lambda2']: lalsimulation.SimInspiralWaveformParamsInsertTidalLambda2( lal_pars, p['lambda2']) if p['dquad_mon1']: lalsimulation.SimInspiralWaveformParamsInsertdQuadMon1( lal_pars, p['dquad_mon1']) if p['dquad_mon2']: lalsimulation.SimInspiralWaveformParamsInsertdQuadMon2( lal_pars, p['dquad_mon2']) if p['numrel_data']: lalsimulation.SimInspiralWaveformParamsInsertNumRelData( lal_pars, str(p['numrel_data'])) if p['modes_choice']: lalsimulation.SimInspiralWaveformParamsInsertModesChoice( lal_pars, p['modes_choice']) if p['frame_axis']: lalsimulation.SimInspiralWaveformParamsInsertFrameAxis( lal_pars, p['frame_axis']) if p['side_bands']: lalsimulation.SimInspiralWaveformParamsInsertSideband( lal_pars, p['side_bands']) return lal_pars
def sngl_inspiral_psd(sngl, waveform, f_min=10, f_max=2048, f_ref=0): # FIXME: uberbank mass criterion. Should find a way to get this from # pipeline output metadata. if waveform == 'o1-uberbank': log.warn('Template is unspecified; using ER8/O1 uberbank criterion') if sngl.mass1 + sngl.mass2 < 4: waveform = 'TaylorF2threePointFivePN' else: waveform = 'SEOBNRv2_ROM_DoubleSpin' approx, ampo, phaseo = get_approximant_and_orders_from_string(waveform) log.info('Selected template: %s', waveform) # Generate conditioned template. params = lal.CreateDict() lalsimulation.SimInspiralWaveformParamsInsertPNPhaseOrder(params, phaseo) lalsimulation.SimInspiralWaveformParamsInsertPNAmplitudeOrder(params, ampo) hplus, hcross = lalsimulation.SimInspiralFD( m1=sngl.mass1*lal.MSUN_SI, m2=sngl.mass2*lal.MSUN_SI, S1x=getattr(sngl, 'spin1x', 0) or 0, S1y=getattr(sngl, 'spin1y', 0) or 0, S1z=getattr(sngl, 'spin1z', 0) or 0, S2x=getattr(sngl, 'spin2x', 0) or 0, S2y=getattr(sngl, 'spin2y', 0) or 0, S2z=getattr(sngl, 'spin2z', 0) or 0, distance=1e6*lal.PC_SI, inclination=0, phiRef=0, longAscNodes=0, eccentricity=0, meanPerAno=0, deltaF=0, f_min=f_min, f_max=f_max, f_ref=f_ref, LALparams=params, approximant=approx) # Force `plus' and `cross' waveform to be in quadrature. h = 0.5 * (hplus.data.data + 1j * hcross.data.data) # For inspiral-only waveforms, nullify frequencies beyond ISCO. # FIXME: the waveform generation functions pick the end frequency # automatically. Shouldn't SimInspiralFD? inspiral_only_waveforms = ( lalsimulation.TaylorF2, lalsimulation.SpinTaylorF2, lalsimulation.TaylorF2RedSpin, lalsimulation.TaylorF2RedSpinTidal, lalsimulation.SpinTaylorT4Fourier) if approx in inspiral_only_waveforms: h[abscissa(hplus) >= get_f_lso(sngl.mass1, sngl.mass2)] = 0 # Drop Nyquist frequency. if len(h) % 2: h = h[:-1] # Create output frequency series. psd = lal.CreateREAL8FrequencySeries( 'signal PSD', 0, hplus.f0, hcross.deltaF, hplus.sampleUnits**2, len(h)) psd.data.data = abs2(h) # Done! return psd
def load_lvcnr_data(filepath, mode, M, dt, inclination, phiRef, \ dist_mpc, f_low=0): """ If f_low = 0, uses the entire NR data. The actual f_low will be returned. """ NRh5File = h5py.File(filepath, 'r') # set mode for NR data params_NR = lal.CreateDict() lalsim.SimInspiralWaveformParamsInsertNumRelData(params_NR, filepath) if mode != 'all': params_NR = set_single_mode(params_NR, mode[0], mode[1]) # Metadata parameters masses: m1 = NRh5File.attrs['mass1'] m2 = NRh5File.attrs['mass2'] m1SI = m1 * M / (m1 + m2) * MSUN_SI m2SI = m2 * M / (m1 + m2) * MSUN_SI distance = dist_mpc * 1.0e6 * PC_SI f_ref = f_low spins = lalsim.SimInspiralNRWaveformGetSpinsFromHDF5File(f_ref, M, \ filepath) s1x = spins[0] s1y = spins[1] s1z = spins[2] s2x = spins[3] s2y = spins[4] s2z = spins[5] # If f_low == 0, update it to the start frequency so that the surrogate # gets the right start frequency if f_low == 0: f_low = NRh5File.attrs['f_lower_at_1MSUN'] / M f_ref = f_low f_low = f_ref lmax = 5 # Generating the NR waveform approx = lalsim.NR_hdf5 hmodes = lalsim.SimInspiralChooseTDModes(phiRef, dt, m1SI, m2SI, \ s1x, s1y, s1z, s2x, s2y, s2z, \ f_low, f_ref, distance, params_NR, lmax, approx) t = np.arange(len(hmodes.mode.data.data)) * dt mode_dict = {} while hmodes is not None: mode_dict['h_l%dm%d' % (hmodes.l, hmodes.m)] = hmodes.mode.data.data hmodes = hmodes.next return t, mode_dict, q, s1x, s1y, s1z, s2x, s2y, s2z, f_low, f_ref '''
def make_waveforms(template, dt, dist, fs, approximant, N, ndet, dets, psds, T_obs, f_low=12.0): """ make waveform""" # define variables template = list(template) m12 = [template[0], template[1]] eta = template[2] mc = template[3] N = T_obs * fs # the total number of time samples dt = 1 / fs # the sampling time (sec) approximant = lalsimulation.IMRPhenomD f_high = fs / 2.0 df = 1.0 / T_obs f_low = df * int(get_fmin(mc, eta, 1.0) / df) f_ref = f_low dist = 1e6 * lal.PC_SI # put it as 1 MPc # generate iota iota = np.arccos(-1.0 + 2.0 * np.random.rand()) print '{}: selected bbh cos(inclination) = {}'.format( time.asctime(), np.cos(iota)) # generate polarisation angle psi = 2.0 * np.pi * np.random.rand() print '{}: selected bbh polarisation = {}'.format(time.asctime(), psi) # print parameters print '{}: selected bbh mass 1 = {}'.format(time.asctime(), m12[0]) print '{}: selected bbh mass 2 = {}'.format(time.asctime(), m12[1]) print '{}: selected bbh eta = {}'.format(time.asctime(), eta) # make waveform hp, hc = lalsimulation.SimInspiralChooseFDWaveform( m12[0] * lal.MSUN_SI, m12[1] * lal.MSUN_SI, 0, 0, 0, 0, 0, 0, dist, iota, 0, 0, 0, 0, df, f_low, f_high, f_ref, lal.CreateDict(), approximant) hp = hp.data.data hc = hc.data.data for psd in psds: hp_1_wht = chris_whiten_data(hp, T_obs, fs, psd.data.data, flag='fd') hc_1_wht = chris_whiten_data(hc, T_obs, fs, psd.data.data, flag='fd') return hp_1_wht, hc_1_wht, get_fmin(mc, eta, 1)
def FD_waveform_test(Mtot, x, approximant, fLow=20.0, fHigh=16384.0, deltaF=0): q = 1.0 / x[0] chi1 = x[1] chi2 = x[2] lambda1 = x[3] lambda2 = x[4] phiRef, fRef = 0.0, fLow distance, inclination = 1.0, 0.0 m1 = q / (1.0 + q) * Mtot m2 = 1.0 / (1.0 + q) * Mtot m1SI, m2SI, chi1, chi2, lambda1, lambda2, nk_max = m1 * lal.MSUN_SI, m2 * lal.MSUN_SI, chi1, chi2, lambda1, lambda2, -1 longAscNodes, eccentricity, meanPerAno = 0, 0, 0 LALpars = lal.CreateDict() LS.SimInspiralWaveformParamsInsertTidalLambda1(LALpars, lambda1) LS.SimInspiralWaveformParamsInsertTidalLambda2(LALpars, lambda2) # Nyquist frequency is set by fHigh # Can set deltaF = 0 to figure out required frequency spacing; the chosen deltaF depends on fLow # Documentation from LALSimInspiral.c # # * This routine can generate TD approximants and transform them into the frequency domain. # * Waveforms are generated beginning at a slightly lower starting frequency and tapers # * are put in this early region so that the waveform smoothly turns on. # * # * If an FD approximant is used, this routine applies tapers in the frequency domain # * between the slightly-lower frequency and the requested f_min. Also, the phase of the # * waveform is adjusted to introduce a time shift. This time shift should allow the # * resulting waveform to be Fourier transformed into the time domain without wrapping # * the end of the waveform to the beginning. # * # * This routine assumes that f_max is the Nyquist frequency of a corresponding time-domain # * waveform, so that deltaT = 0.5 / f_max. If deltaF is set to 0 then this routine computes # * a deltaF that is small enough to represent the Fourier transform of a time-domain waveform. # * If deltaF is specified but f_max / deltaF is not a power of 2, and the waveform approximant # * is a time-domain approximant, then f_max is increased so that f_max / deltaF is the next # * power of 2. (If the user wishes to discard the extra high frequency content, this must # * be done separately.) hp, hc = LS.SimInspiralFD(m1SI, m2SI, 0.0, 0.0, chi1, 0.0, 0.0, chi2, distance, inclination, phiRef, longAscNodes, eccentricity, meanPerAno, deltaF, fLow, fHigh, fRef, LALpars, approximant) fHz = np.arange(hp.data.length) * hp.deltaF h = hp.data.data + 1j * hc.data.data return hp.deltaF
def recalculate_waveform(conf): '''Reads single data set and returns both the reference waveform and the newly calculated waveform with the same parameters. Returns: [hpref, hcref, hpnew, hcnew] ''' approx = lalsim.GetApproximantFromString( conf.get('approximant', 'approximant')) domain = conf.get('approximant', 'domain') if domain == 'TD': hpref, hcref = [ np.array(map(float, (conf.get('waveform-data', l)).split())) for l in ['hp', 'hc'] ] if domain == 'FD': hpRref, hpIref, hcRref, hcIref = [ np.array(map(float, (conf.get('waveform-data', l)).split())) for l in ['hp_real', 'hp_imag', 'hc_real', 'hc_imag'] ] hpref = hpRref + 1j * hpIref hcref = hcRref + 1j * hcIref names = CheckReferenceWaveforms.paramnames[domain] parDict = dict([ (p, CheckReferenceWaveforms.paramtype[p](conf.get('parameters', p))) for p in conf.options('parameters') ]) parDict['m1'] *= lal.MSUN_SI parDict['m2'] *= lal.MSUN_SI parDict['distance'] *= (1.e6 * lal.PC_SI) params = [parDict[name] for name in names] LALpars = lal.CreateDict() try: tmp = parDict['lambda1'] except: tmp = 0. if (tmp): lalsim.SimInspiralWaveformParamsInsertTidalLambda1( LALpars, parDict['lambda1']) try: tmp = parDict['lambda2'] except: tmp = 0. if (tmp): lalsim.SimInspiralWaveformParamsInsertTidalLambda2( LALpars, parDict['lambda2']) params.append(LALpars) params.append(approx) hp, hc = waveformgenerator(domain, params) return [hpref, hcref, hp, hc]
def _eval_fit(self, fit_params, fit_type, extra_params_dict): """ Evaluates a particular fit for NRSur7dq4Remnant using the fit_params returned by _get_fit_params(). fit_type can be one of "FinalMass", "FinalSpin" or "RecoilKick". Passing extra_params_dict = {"unlimited_extrapolation": True}, will ignore any extrapolation errors. USE AT YOUR OWN RISK!! Default: False. """ q, chiA_vec, chiB_vec, quat_fitnode, orbphase_fitnode = fit_params LALParams = lal.CreateDict() if extra_params_dict["unlimited_extrapolation"]: lal.DictInsertUINT4Value(LALParams, "unlimited_extrapolation", 1) if fit_type == "FinalMass": # FinalMass is given as a fraction of total mass val = lalsim.NRSur7dq4Remnant(q, chiA_vec[0], chiA_vec[1], chiA_vec[2], chiB_vec[0], chiB_vec[1], chiB_vec[2], "mf", LALParams).data[0] else: if fit_type == "FinalSpin": val = lalsim.NRSur7dq4Remnant(q, chiA_vec[0], chiA_vec[1], chiA_vec[2], chiB_vec[0], chiB_vec[1], chiB_vec[2], "chif", LALParams).data elif fit_type == "RecoilKick": val = lalsim.NRSur7dq4Remnant(q, chiA_vec[0], chiA_vec[1], chiA_vec[2], chiB_vec[0], chiB_vec[1], chiB_vec[2], "vf", LALParams).data else: raise ValueError("Invalid fit_type=%s. This model only allows " "'FinalMass', 'FinalSpin' and 'RecoilKick'." % fit_type) # The fits are constructed in the coorbital frame at t=-100M. # If quat_fitnode is None, this means that no spin evolution # was done and the return values should be in the coorbital frame # at t=-100. So, we don't need any further transformations. if quat_fitnode is not None: # If quat_fitnode is not None, we transform the remnant vectors # into the LAL inertial frame, which is the same as the # coorbital frame at omega0. This is done using the # coprecessing frame quaternion and orbital phase at t=-100M. # These are defined w.r.t. the reference LAL inertial frame # defined at omega0. val = quaternion_utils.transform_vector_coorb_to_inertial(val, \ orbphase_fitnode, quat_fitnode) return np.atleast_1d(val)
def get_snr_at_z_lalsimulation(cosmo, z, mass1, mass2, f_low, f_high, psd): """Calculate optimal SNR the LALSimulation way.""" params = lal.CreateDict() lalsimulation.SimInspiralWaveformParamsInsertRedshift(params, z) # "Signal" waveform with requested inclination angle. # Take (arbitrarily) only the plus polarization. h, _ = lalsimulation.SimInspiralFD( mass1 * lal.MSUN_SI, mass2 * lal.MSUN_SI, 0, 0, 0, 0, 0, 0, cosmo.comoving_distance(z).to_value(u.m), 0, 0, 0, 0, 0, 1e-3 * (f_high - f_low), f_low, f_high, f_low, params, lalsimulation.IMRPhenomPv2) return lalsimulation.MeasureSNRFD(h, psd, f_low, f_high)
def _compute_waveform(self, df, f_final): phi0 = 0 # This is a reference phase, and not an intrinsic parameter LALpars = lal.CreateDict() approx = lalsim.GetApproximantFromString(self.approx_name) hplus_fd, hcross_fd = lalsim.SimInspiralChooseFDWaveform( self.m1 * MSUN_SI, self.m2 * MSUN_SI, 0., 0., self.spin1z, 0., 0., self.spin2z, 1.e6 * PC_SI, 0., phi0, 0., 0., 0., df, self.flow, f_final, self.flow, LALpars, approx) # Must set values greater than _get_f_final to 0 act_f_max = self._get_f_final() f_max_idx = int(act_f_max / df + 0.999) hplus_fd.data.data[f_max_idx:] = 0 return hplus_fd
def test_liv_flag_disabled_by_default(): """ This tests that the liv flag is disabled by default. Additionally it checks the flag may be enabled properly. `expected_result = 0` is the default value of the LIV flag """ LALpars = lal.CreateDict() expected_result = 0 actual_result = is_liv_enabled_by_default(LALpars) np.testing.assert_approx_equal(actual_result, expected_result, 7, "Incorrect setting of LIV flag by default") ## Now check if it can be inserted correctly expected_result = 1 actual_result = enable_liv(LALpars) np.testing.assert_approx_equal(actual_result, expected_result, 7, "LIV flag not inserted correctly")
def test_correct_liv_pars(): """ This tests if the default LIV parameters are correct. Additionally it tests LIV parameters are being inserted correctly. `expected_result = np.array([100.0,1.0,0.0])` are the default values of log10lambda_eff, A_sign and alpha respectively """ LALpars = lal.CreateDict() expected_result = np.array([100.0, 1.0, 0.0]) actual_result = np.array(read_liv_params(LALpars)) np.testing.assert_almost_equal(actual_result, expected_result, 7, "Default LIV values are not set correctly") ## Checking if parameters can be inserted properly set_liv_pars(LALpars, 44.,-1.,1.5) expected_result = np.array([44., -1., 1.5]) actual_result = np.array(read_liv_params(LALpars)) np.testing.assert_almost_equal(actual_result, expected_result, 7, "LIV values are not inserted correctly")
def test_match_LalBBH_nonGR(self): parameters = copy(self.parameters) parameters.update(self.waveform_kwargs) wf_dict = lal.CreateDict() lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi0(wf_dict, 1.) parameters['lal_waveform_dictionary'] = wf_dict freqseq = bilby.gw.source.binary_black_hole_frequency_sequence( self.frequency_array, **parameters ) lalbbh = bilby.gw.source.lal_binary_black_hole( self.frequency_array, **parameters ) self.assertEqual(freqseq.keys(), lalbbh.keys()) for mode in freqseq: diff = np.sum(np.abs(freqseq[mode] - lalbbh[mode][self.full_frequencies_to_sequence])**2.) norm = np.sum(np.abs(freqseq[mode])**2.) self.assertLess(diff / norm, 1e-15)
def _get_surrogate_dynamics(self, q, chiA0, chiB0, init_quat, \ init_orbphase, omega_ref, unlimited_extrapolation): """ A wrapper for NRSur7dq4 dynamics. Inputs: q: Mass ratio, mA/mB >= 1. chiA0: Dimless spin of BhA in the coorbital frame at omega_ref. chiB0: Dimless spin of BhB in the coorbital frame at omega_ref. init_quat: Coprecessing frame quaternion at omega_ref. init_orbphase: Orbital phase in the coprecessing frame at omega_ref. omega_ref: Orbital frequency in the coprecessing frame at the reference epoch where the input spins are given. Note: This is total-mass times the angular orbital frequency. unlimited_extrapolation: If True, allows unlimited extrapolation to regions well outside the surrogate's training region. Else, raises an error. Outputs: t_dyn: Time values at which the dynamics are returned. These are nonuniform and sparse. copr_quat: Time series of coprecessing frame quaternions. orbphase: Orbital phase time series in the coprecessing frame. chiA_copr: Time series of spin of BhA in the coprecessing frame. chiB_copr: Time series of spin of BhB in the coprecessing frame. """ approxTag = lalsim.SimInspiralGetApproximantFromString("NRSur7dq4") LALParams = lal.CreateDict() if unlimited_extrapolation: lal.DictInsertUINT4Value(LALParams, "unlimited_extrapolation", 1) t_dyn, quat0, quat1, quat2, quat3, orbphase, chiAx, chiAy, chiAz, \ chiBx, chiBy, chiBz = lalsim.PrecessingNRSurDynamics(q, \ chiA0[0], chiA0[1], chiA0[2], chiB0[0], chiB0[1], chiB0[2], \ omega_ref, init_quat[0], init_quat[1], init_quat[2], init_quat[3], \ init_orbphase, LALParams, approxTag) t_dyn = t_dyn.data orbphase = orbphase.data copr_quat = np.array([quat0.data, quat1.data, quat2.data, quat3.data]) chiA_copr = np.array([chiAx.data, chiAy.data, chiAz.data]).T chiB_copr = np.array([chiBx.data, chiBy.data, chiBz.data]).T return t_dyn, copr_quat, orbphase, chiA_copr, chiB_copr
def simulate_waveform(self, m1, m2, dl, inc, phi, S1x=0., S1y=0., S1z=0., S2x=0., S2y=0., S2z=0., lAN=0., e=0., Ano=0.): """ Simulates frequency domain inspiral waveform Parameters ---------- m1, m2 : float observed source masses in kg dl : float luminosity distance in Mpc inc: float source inclination in radians phi : float source reference phase in radians S1x, S1y, S1z : float, optional x,y,z-components of dimensionless spins of body 1 (default=0.) S2x, S2y, S2z : float, optional x,y,z-components of dimensionless spin of body 2 (default=0.) lAN: float, optional longitude of ascending nodes (default=0.) e: float, optional eccentricity at reference epoch (default=0.) Ano: float, optional mean anomaly at reference epoch (default=0.) Returns ------- lists hp and hc """ hp, hc = lalsim.SimInspiralChooseFDWaveform( m1, m2, S1x, S1y, S1z, S2x, S2y, S2z, dl*1e6*lal.PC_SI, inc, phi, lAN, e, Ano, self.df, self.f_min, self.f_max, 20, lal.CreateDict(), lalsim.IMRPhenomD) hp = hp.data.data hc = hc.data.data return hp,hc
def gen_fs(fs, T_obs, par): """ generates a BBH timedomain signal """ N = T_obs * fs # the total number of time samples dt = 1 / fs # the sampling time (sec) approximant = lalsimulation.IMRPhenomD f_high = fs / 2.0 df = 1.0 / T_obs f_low = df * int(par.fmin / df) # used to be par.fmin f_ref = f_low dist = 1e6 * lal.PC_SI # put it as 1 MPc # make waveform hp, hc = lalsimulation.SimInspiralChooseFDWaveform( par.m1 * lal.MSUN_SI, par.m2 * lal.MSUN_SI, 0, 0, 0, 0, 0, 0, dist, par.iota, 0, 0, 0, 0, df, f_low, f_high, f_ref, lal.CreateDict(), approximant) return hp.data.data, hc.data.data
def generate_waveform(m1, m2): mtot = (m1 + m2) * lal.MTSUN_SI f_min = 20.0 f_max = 2048.0 df = 1. / 32. f_rescaled_min = f_min * mtot f_rescaled_max = f_max * mtot df_rescaled = mtot * df hptilde, hctilde = lalsim.SimInspiralChooseFDWaveform( #where is its definition and documentation???? m1 * lalsim.lal.MSUN_SI, #m1 m2 * lalsim.lal.MSUN_SI, #m2 0., 0., .5, #spin vector 1 0., 0., 0., #spin vector 2 1. * 1e6 * lalsim.lal.PC_SI, #distance to source 0., #inclination 0., #phi ref 0., #longAscNodes 0., #eccentricity 0., #meanPerAno 1e-3, # frequency incremental step f_min, # lowest value of frequency f_max, # highest value of frequency f_min, #some reference value of frequency (??) lal.CreateDict(), #some lal dictionary # lalsim.GetApproximantFromString('IMRPHenomPv2') #approx method for the model lalsim.GetApproximantFromString('SEOBNRv4_ROM' ) #approx method for the model ) frequency = np.linspace(0.0, f_max, hptilde.data.length) rescaled_frequency = frequency * mtot print(mtot) return frequency, rescaled_frequency, hptilde.data.data + 1j * hctilde.data.data
def time_domain(self, binary): """ Compute time-domain template model of the gravitational wave for a given compact binary. Ref: http://software.ligo.org/docs/lalsuite/lalsimulation/group__lalsimulation__inspiral.html """ # build structure containing variable with default values extra_params = lal.CreateDict() DictInsertREAL8Value(extra_params,"Lambda1", binary.lambda1) SimInspiralWaveformParamsInsertTidalLambda1(extra_params, binary.lambda1) DictInsertREAL8Value(extra_params,"Lambda2", binary.lambda2) SimInspiralWaveformParamsInsertTidalLambda2(extra_params, binary.lambda2) DictInsertINT4Value(extra_params, "amplitude0", self.amplitude0) DictInsertINT4Value(extra_params, "phase0", self.phase0) return SimInspiralTD(binary.mass1 * LAL_MSUN_SI, binary.mass2 * LAL_MSUN_SI, \ binary.spin1['x'], binary.spin1['y'], binary.spin1['z'], \ binary.spin2['x'], binary.spin2['y'], binary.spin2['z'], \ binary.distance * 1.0e6 * LAL_PC_SI, math.radians(binary.iota), \ math.radians(self.phi_ref), math.radians(binary.longAscNodes), \ binary.eccentricity, binary.meanPerAno, \ 1.0 / self.sampling_rate, self.freq_min, self.freq_ref, \ extra_params, self.approximant)
def generate_LAL_waveform(approximant, q, chiA0, chiB0, dt, M, \ dist_mpc, f_low, f_ref, inclination=0, phi_ref=0., ellMax=None, \ single_mode=None): distance = dist_mpc * 1.0e6 * PC_SI approxTag = lalsim.SimInspiralGetApproximantFromString(approximant) # component masses of the binary m1_kg = M * MSUN_SI * q / (1. + q) m2_kg = M * MSUN_SI / (1. + q) if single_mode is not None and ellMax is not None: raise Exception("Specify only one of single_mode or ellMax") dictParams = lal.CreateDict() # If ellMax, load all modes with ell<=ellMax if ellMax is not None: ma = lalsim.SimInspiralCreateModeArray() for ell in range(2, ellMax + 1): lalsim.SimInspiralModeArrayActivateAllModesAtL(ma, ell) lalsim.SimInspiralWaveformParamsInsertModeArray(dictParams, ma) elif single_mode is not None: # If a single_mode is given, load only that mode (l,m) and (l,-m) dictParams = set_single_mode(dictParams, single_mode[0], single_mode[1]) hp, hc = lalsim.SimInspiralChooseTDWaveform(\ m1_kg, m2_kg, chiA0[0], chiA0[1], chiA0[2], \ chiB0[0], chiB0[1], chiB0[2], \ distance, inclination, phi_ref, 0, 0, 0,\ dt, f_low, f_ref, dictParams, approxTag) h = np.array(hp.data.data - 1.j * hc.data.data) t = dt * np.arange(len(h)) return t, h
def _check_lal_pars(p): """ Create a laldict object from the dictionary of waveform parameters Parameters ---------- p: dictionary The dictionary of lalsimulation paramaters Returns ------- laldict: LalDict The lal type dictionary to pass to the lalsimulation waveform functions. """ lal_pars = lal.CreateDict() #nonGRparams can be straightforwardly added if needed, however they have to # be invoked one by one if p['phase_order']!=-1: lalsimulation.SimInspiralWaveformParamsInsertPNPhaseOrder(lal_pars,int(p['phase_order'])) if p['amplitude_order']!=-1: lalsimulation.SimInspiralWaveformParamsInsertPNAmplitudeOrder(lal_pars,int(p['amplitude_order'])) if p['spin_order']!=-1: lalsimulation.SimInspiralWaveformParamsInsertPNSpinOrder(lal_pars,int(p['spin_order'])) if p['tidal_order']!=-1: lalsimulation.SimInspiralWaveformParamsInsertPNTidalOrder(lal_pars, p['tidal_order']) if p['eccentricity_order']!=-1: lalsimulation.SimInspiralWaveformParamsInsertPNEccentricityOrder(lal_pars, p['eccentricity_order']) if p['lambda1'] is not None: lalsimulation.SimInspiralWaveformParamsInsertTidalLambda1(lal_pars, p['lambda1']) if p['lambda2'] is not None: lalsimulation.SimInspiralWaveformParamsInsertTidalLambda2(lal_pars, p['lambda2']) if p['lambda_octu1'] is not None: lalsimulation.SimInspiralWaveformParamsInsertTidalOctupolarLambda1(lal_pars, p['lambda_octu1']) if p['lambda_octu2'] is not None: lalsimulation.SimInspiralWaveformParamsInsertTidalOctupolarLambda2(lal_pars, p['lambda_octu2']) if p['quadfmode1'] is not None: lalsimulation.SimInspiralWaveformParamsInsertTidalQuadrupolarFMode1(lal_pars, p['quadfmode1']) if p['quadfmode2'] is not None: lalsimulation.SimInspiralWaveformParamsInsertTidalQuadrupolarFMode2(lal_pars, p['quadfmode2']) if p['octufmode1'] is not None: lalsimulation.SimInspiralWaveformParamsInsertTidalOctupolarFMode1(lal_pars, p['octufmode1']) if p['octufmode2'] is not None: lalsimulation.SimInspiralWaveformParamsInsertTidalOctupolarFMode2(lal_pars, p['octufmode2']) if p['dquad_mon1'] is not None: lalsimulation.SimInspiralWaveformParamsInsertdQuadMon1(lal_pars, p['dquad_mon1']) if p['dquad_mon2'] is not None: lalsimulation.SimInspiralWaveformParamsInsertdQuadMon2(lal_pars, p['dquad_mon2']) if p['numrel_data']: lalsimulation.SimInspiralWaveformParamsInsertNumRelData(lal_pars, str(p['numrel_data'])) if p['modes_choice']: lalsimulation.SimInspiralWaveformParamsInsertModesChoice(lal_pars, p['modes_choice']) if p['frame_axis']: lalsimulation.SimInspiralWaveformParamsInsertFrameAxis(lal_pars, p['frame_axis']) if p['side_bands']: lalsimulation.SimInspiralWaveformParamsInsertSideband(lal_pars, p['side_bands']) if p['mode_array'] is not None: ma = lalsimulation.SimInspiralCreateModeArray() for l,m in p['mode_array']: lalsimulation.SimInspiralModeArrayActivateMode(ma, l, m) lalsimulation.SimInspiralWaveformParamsInsertModeArray(lal_pars, ma) #TestingGR parameters: if p['dchi0'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi0(lal_pars,p['dchi0']) if p['dchi1'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi1(lal_pars,p['dchi1']) if p['dchi2'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi2(lal_pars,p['dchi2']) if p['dchi3'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi3(lal_pars,p['dchi3']) if p['dchi4'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi4(lal_pars,p['dchi4']) if p['dchi5'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi5(lal_pars,p['dchi5']) if p['dchi5l'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi5L(lal_pars,p['dchi5l']) if p['dchi6'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi6(lal_pars,p['dchi6']) if p['dchi6l'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi6L(lal_pars,p['dchi6l']) if p['dchi7'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDChi7(lal_pars,p['dchi7']) if p['dalpha1'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha1(lal_pars,p['dalpha1']) if p['dalpha2'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha2(lal_pars,p['dalpha2']) if p['dalpha3'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha3(lal_pars,p['dalpha3']) if p['dalpha4'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha4(lal_pars,p['dalpha4']) if p['dalpha5'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDAlpha5(lal_pars,p['dalpha5']) if p['dbeta1'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDBeta1(lal_pars,p['dbeta1']) if p['dbeta2'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDBeta2(lal_pars,p['dbeta2']) if p['dbeta3'] is not None: lalsimulation.SimInspiralWaveformParamsInsertNonGRDBeta3(lal_pars,p['dbeta3']) return lal_pars
def sngl_inspiral_psd(waveform, mass1, mass2, f_min=10, f_final=None, f_ref=None, **kwargs): # FIXME: uberbank mass criterion. Should find a way to get this from # pipeline output metadata. if waveform == 'o1-uberbank': log.warning('Template is unspecified; ' 'using ER8/O1 uberbank criterion') if mass1 + mass2 < 4: waveform = 'TaylorF2threePointFivePN' else: waveform = 'SEOBNRv2_ROM_DoubleSpin' elif waveform == 'o2-uberbank': log.warning('Template is unspecified; ' 'using ER10/O2 uberbank criterion') if mass1 + mass2 < 4: waveform = 'TaylorF2threePointFivePN' else: waveform = 'SEOBNRv4_ROM' approx, ampo, phaseo = get_approximant_and_orders_from_string(waveform) log.info('Selected template: %s', waveform) # Generate conditioned template. params = lal.CreateDict() lalsimulation.SimInspiralWaveformParamsInsertPNPhaseOrder(params, phaseo) lalsimulation.SimInspiralWaveformParamsInsertPNAmplitudeOrder(params, ampo) hplus, hcross = lalsimulation.SimInspiralFD( m1=float(mass1) * lal.MSUN_SI, m2=float(mass2) * lal.MSUN_SI, S1x=float(kwargs.get('spin1x') or 0), S1y=float(kwargs.get('spin1y') or 0), S1z=float(kwargs.get('spin1z') or 0), S2x=float(kwargs.get('spin2x') or 0), S2y=float(kwargs.get('spin2y') or 0), S2z=float(kwargs.get('spin2z') or 0), distance=1e6 * lal.PC_SI, inclination=0, phiRef=0, longAscNodes=0, eccentricity=0, meanPerAno=0, deltaF=0, f_min=f_min, # Note: code elsewhere ensures that the sample rate is at least two # times f_final; the factor of 2 below is just a safety factor to make # sure that the sample rate is 2-4 times f_final. f_max=ceil_pow_2(2 * (f_final or 2048)), f_ref=float(f_ref or 0), LALparams=params, approximant=approx) # Force `plus' and `cross' waveform to be in quadrature. h = 0.5 * (hplus.data.data + 1j * hcross.data.data) # For inspiral-only waveforms, nullify frequencies beyond ISCO. # FIXME: the waveform generation functions pick the end frequency # automatically. Shouldn't SimInspiralFD? inspiral_only_waveforms = (lalsimulation.TaylorF2, lalsimulation.SpinTaylorF2, lalsimulation.TaylorF2RedSpin, lalsimulation.TaylorF2RedSpinTidal, lalsimulation.SpinTaylorT4Fourier) if approx in inspiral_only_waveforms: h[abscissa(hplus) >= get_f_lso(mass1, mass2)] = 0 # Throw away any frequencies above high frequency cutoff h[abscissa(hplus) >= (f_final or 2048)] = 0 # Drop Nyquist frequency. if len(h) % 2: h = h[:-1] # Create output frequency series. psd = lal.CreateREAL8FrequencySeries('signal PSD', 0, hplus.f0, hcross.deltaF, hplus.sampleUnits**2, len(h)) psd.data.data = abs2(h) # Done! return psd
def lalsim_FD_waveform(m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, theta_jn, phase, duration, dL, fmax, lambda_1=None, lambda_2=None, **kwarg): mass1 = m1 * lal.MSUN_SI mass2 = m2 * lal.MSUN_SI spin_1x = s1x spin_1y = s1y spin_1z = s1z spin_2x = s2x spin_2y = s2y spin_2z = s2z iota = theta_jn phaseC = phase # Phase is hard coded to be zero eccentricity = 0 longitude_ascending_nodes = 0 mean_per_ano = 0 waveform_arg = dict(minimum_freq=20.0, reference_frequency=20) waveform_arg.update(kwarg) dL = dL * lal.PC_SI * 1e6 # MPC --> Km approximant = lalsim.GetApproximantFromString( waveform_arg["waveform_approximant"]) flow = waveform_arg["minimum_freq"] delta_freq = 1.0 / duration maximum_frequency = fmax # 1024.0 # ISCO(m1, m2) fref = waveform_arg["reference_frequency"] waveform_dictionary = lal.CreateDict() if lambda_1 is not None: lalsim.SimInspiralWaveformParamsInsertTidalLambda1( waveform_dictionary, float(lambda_1)) if lambda_2 is not None: lalsim.SimInspiralWaveformParamsInsertTidalLambda2( waveform_dictionary, float(lambda_2)) hplus, hcross = lalsim.SimInspiralChooseFDWaveform( mass1, mass2, spin_1x, spin_1y, spin_1z, spin_2x, spin_2y, spin_2z, dL, iota, phaseC, longitude_ascending_nodes, eccentricity, mean_per_ano, delta_freq, flow, maximum_frequency, fref, waveform_dictionary, approximant, ) h_plus = hplus.data.data[:] h_cross = hcross.data.data[:] return {"plus": h_plus, "cross": h_cross}