Ejemplo n.º 1
0
def _lalsim_fd_waveform(**p):
    flags = lalsimulation.SimInspiralCreateWaveformFlags()
    lalsimulation.SimInspiralSetSpinOrder(flags, p['spin_order'])
    lalsimulation.SimInspiralSetTidalOrder(flags, p['tidal_order'])

    hp1, hc1 = lalsimulation.SimInspiralChooseFDWaveform(
        float(p['coa_phase']), p['delta_f'],
        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']), float(p['f_lower']),
        float(p['f_final']), float(p['f_ref']),
        pnutils.megaparsecs_to_meters(float(p['distance'])),
        float(p['inclination']), float(p['lambda1']),
        float(p['lambda2']), flags, None, int(p['amplitude_order']),
        int(p['phase_order']), _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)

    return hp, hc
def get_htildas(m1,m2,dist,
		   phase=0., 
		   df=1e-2,  
		   s1x=0.0, 
		   s1y=0.0, 
		   s1z=0.0, 
		   s2x=0.0, 
		   s2y=0.0, 
		   s2z=0.0, 
		   fmin=1.,
		   fmax=0.,
		   fref=1.,  
		   iota=0., 
		   longAscNodes=0.,
		   eccentricity=0.,
		   meanPerAno=0.,
		   LALpars=None,
		   approx=ls.IMRPhenomD
		   ):
	#hplus_tilda, hcross_tilda = ls.SimInspiralChooseFDWaveform(phase, df, m1*lal.MSUN_SI, m2*lal.MSUN_SI, s1x, s1y, s1z, s2x, s2y, s2z, fmin, fmax, fref, dist*(1E6 * ls.lal.PC_SI), iota, lambda1, lambda2, waveFlags, nonGRparams, amp_order, phase_order, approx)
	hplus_tilda, hcross_tilda = ls.SimInspiralChooseFDWaveform(m1*lal.MSUN_SI, m2*lal.MSUN_SI, s1x, s1y, s1z, s2x, s2y, s2z, dist*(1E6 * ls.lal.PC_SI),iota,phase, longAscNodes,eccentricity,meanPerAno,df,fmin, fmax, fref,LALpars,approx)
	freqs=array([hplus_tilda.f0+i*hplus_tilda.deltaF for i in arange(hplus_tilda.data.length)])
	return hplus_tilda.data.data,hcross_tilda.data.data,freqs
Ejemplo n.º 3
0
    def _compute_waveform(self, df, f_final):

        phi0 = 0  # This is a reference phase, and not an intrinsic parameter
        approx = lalsim.GetApproximantFromString(self.approximant)

        if lalsim.SimInspiralImplementedFDApproximants(approx):
            hplus_fd, hcross_fd = lalsim.SimInspiralChooseFDWaveform(
                self.m1 * MSUN_SI, self.m2 * MSUN_SI,
                0., 0., self.spin1z, 0., 0., self.spin2z,
                1e6*PC_SI, 0., 0.,
                0., 0., 0.,
                df, self.flow, f_final, self.flow,
                None, approx)

        else:
            hplus_fd, hcross_fd = lalsim.SimInspiralFD(
                phi0, df, self.m1*MSUN_SI, self.m2*MSUN_SI, 0,
                0, self.spin1z, 0, 0, self.spin2z,
                1.e6*PC_SI, 0., 0.,
                0., 0., 0.,
                df, self.flow, f_final, 40.,
                None, approx)
        return hplus_fd
Ejemplo n.º 4
0
def compute_modulus_quad(paramspoint, known_quad_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
    hp_quad_tmp = (numpy.absolute(hp_tmp))**2
    residual = hp_quad_tmp
    for k in numpy.arange(0, len(known_quad_bases)):
        residual -= proj(known_quad_bases[k], hp_quad_tmp)
    modulus = numpy.sqrt(numpy.vdot(residual, residual))
    return modulus
Ejemplo n.º 5
0
def generate_LAL_FDwaveform(approximant, q, chiA0, chiB0, df, M, \
    dist_mpc, f_min, f_max, 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.SimInspiralChooseFDWaveform(\
        m1_kg, m2_kg, chiA0[0], chiA0[1], chiA0[2], \
        chiB0[0], chiB0[1], chiB0[2], \
        distance, inclination, phi_ref, 0, 0, 0,\
        df, f_min, f_max, f_ref, dictParams, approxTag)

    h = np.array(hp.data.data - 1.j * hc.data.data)
    f = np.arange(f_min, f_min + df * len(h), df)

    return f, h
Ejemplo n.º 6
0
def gen_bbh(fs,
            T_obs,
            psds,
            dets=['H1'],
            beta=[0.75, 0.95],
            par=None,
            gw_tmp=False):
    """ generates a BBH timedomain signal

    Parameters
    ----------
    fs:
        sampling frequency
    T_obs:
        observation time window
    psds:
        power spectral desnity to use
    dets:
        detector
    beta:
        fractional range of time series to place peak signals
    par:
        class containing parameters of waveform to generate
    gw_tmp:
        if True: make a template exactly like event to do PE on
    
    Returns
    -------
    ts:
        h-plus and h-cross combined GW time series waveform
    hp:
        h-plus GW time series waveform
    hc:
        h-cross GW time series waveform
    ts:
        this is redundant. need to remove    
    """
    N = T_obs * fs  # the total number of time samples
    dt = 1 / fs  # time resolution (sec)
    f_low = 40  # lowest frequency of waveform (Hz)
    amplitude_order = 0  # amplitude order
    phase_order = 7  # phase order
    f_max = fs / 2  # maximum allowed frequency for FD waveforms
    approximant = lalsimulation.IMRPhenomPv2  # waveform approximant
    dist = 410e6 * lal.PC_SI  # waveform distance

    # if making event-like template, then fix distance
    if gw_tmp:
        dist = 410e6 * lal.PC_SI

    # 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, par.phi, 0, 0, 0, 1 / T_obs, f_low, f_max, f_low,
        lal.CreateDict(), approximant)

    whiten_hp = whiten_data(hp.data.data, T_obs, fs, psds, flag='fd')
    whiten_hc = whiten_data(hc.data.data, T_obs, fs, psds, flag='fd')

    orig_hp = np.roll(np.fft.irfft(whiten_hp, T_obs * fs), int(-fs))
    orig_hc = np.roll(np.fft.irfft(whiten_hc, T_obs * fs), int(-fs))

    # transform back into time domain in upcoming sections

    # compute reference idx
    ref_idx = np.argmax(orig_hp**2 + orig_hc**2)

    # the start index of the central region
    sidx = int(0.5 * fs * T_obs * (safe - 1.0) / safe)

    # make aggressive window to cut out signal in central region
    # window is non-flat for 1/8 of desired Tobs
    # the window has dropped to 50% at the Tobs boundaries
    win = np.zeros(N)
    tempwin = tukey(int((16.0 / 15.0) * N / safe), alpha=1.0 / 8.0)
    win[int((N - tempwin.size) / 2):int((N - tempwin.size) / 2) +
        tempwin.size] = tempwin

    # loop over detectors
    ndet = 1
    ts = np.zeros((ndet, N))
    hp = np.zeros((ndet, N))
    hc = np.zeros((ndet, N))
    intsnr = []
    j = 0

    for det in dets:

        # make signal - apply antenna and shifts
        ht_shift, hp_shift, hc_shift = make_bbh(orig_hp, orig_hc, fs, par.ra,
                                                par.dec, par.psi, det)

        # place signal into timeseries - including shift
        ht_temp = ht_shift[int(ref_idx - par.idx -
                               11):]  # use 21 if sampling at 2kHz
        hp_temp = hp_shift[int(ref_idx - par.idx -
                               11):]  # use 21 if sampling at 2kHz
        hc_temp = hc_shift[int(ref_idx - par.idx -
                               11):]  # use 21 if sampling at 2kHz

        if len(ht_temp) < N:
            ts[j, :len(ht_temp)] = ht_temp
            hp[j, :len(ht_temp)] = hp_temp
            hc[j, :len(ht_temp)] = hc_temp
        else:
            ts[j, :] = ht_temp[:N]
            hp[j, :] = hp_temp[:N]
            hc[j, :] = hc_temp[:N]

        # apply aggressive window to cut out signal in central region
        # window is non-flat for 1/8 of desired Tobs
        # the window has dropped to 50% at the Tobs boundaries
        ts[j, :] *= win
        hp[j, :] *= win
        hc[j, :] *= win

    return ts, hp, hc, ts
Ejemplo n.º 7
0
def create_dataset_FD(N_data,
                      N_grid=None,
                      filename=None,
                      q_range=(1., 5.),
                      m2_range=20.,
                      s1_range=(-0.8, 0.8),
                      s2_range=(-0.8, 0.8),
                      log_space=True,
                      f_high=2000,
                      f_step=1e-2,
                      f_max=None,
                      f_min=None,
                      approximant="IMRPhenomPv2"):
    """
	Create a dataset for training a ML model to fit GW waveforms in frequency domain.
	The dataset consists in 3 parameters theta=(q, spin1z, spin2z) associated to the waveform computed in frequency domain for a grid of N_grid points in the range given by the user.
	More specifically, data are stored in 3 vectors:
		theta_vector	vector holding source parameters q, spin1, spin2
		amp_vector		vector holding amplitudes for each source evaluated at some N_grid equally spaced points
		ph_vector		vector holding phase for each source evaluated at some N_grid equally spaced points
	This routine add N_data data to filename if one is specified (if file is not empty it must contain data with the same N_grid); otherwise the datasets are returned as np vectors. 
	All the waves are evaluated at a constant distance of 1Mpc. Values of q and m2 are drawn randomly in the range given by the user: it holds m1 = q *m2 M_sun.
	The waveforms are computed from f_low = 15 to f_high with a step f_step and then evaluated at some N_grid grid points equally spaced in range [f_min, f_max]
	Dataset can be loaded with load_dataset
	Input:
		N_data			size of dataset
		N_grid			number of points to be sampled in the grid (if None every point generated is saved)
		filename		name of the file to save dataset in (If is None, nothing is saved on a file)
		q_range			tuple with range for random q values. if single value, q is kept fixed at that value
		m2_range		tuple with range for random m2 values. if single value, m2 is kept fixed at that value
		spin_mag_max_1	tuple with range for random spin #1 values. if single value, s1 is kept fixed at that value
		spin_mag_max_2	tuple with range for random spin #1 values. if single value, s2 is kept fixed at that value
		log_space		whether grid should be computed in logspace
		f_high			highest frequency to compute
		f_step			step considered for computation of waveforms
		f_max			maximum frequency returned to the user (if None is the same as f_max)
		f_min			minimum frequency returned to the user (if None is the same as f_low = 15)
		approximant	string for the approximant model to be used (in lal convention)
	Output:
		if filename is given
			None
		if filename is not given
			theta_vector (N_data,3)		vector holding ordered set of parameters used to generate amp_dataset and ph_dataset
			amp_dataset (N_data,N_grid)	dataset with amplitudes
			ph_dataset (N_data,N_grid)	dataset with phases
			frequencies (N_grid,)		vector holding frequencies at which waves are evaluated
	"""
    if f_max is None:
        f_max = f_high
    if f_min is None:
        f_min = 1.
    f_low = f_min
    K = int(
        (f_max - f_min) /
        f_step)  #number of data points to be taken from the returned vector
    if N_grid is None:
        N_grid = K
    full_freq = np.arange(f_low, f_max,
                          f_step)  #full frequency vector as returned by lal
    d = 1.
    LALpars = lal.CreateDict()
    approx = lalsim.SimInspiralGetApproximantFromString(approximant)

    #allocating storage for temp vectors to save a single WF
    temp_amp = np.zeros((N_grid, ))
    temp_ph = np.zeros((N_grid, ))
    temp_theta = np.zeros((3, ))

    #setting frequencies to be returned to user
    if log_space:
        frequencies = np.logspace(np.log10(f_min), np.log10(f_max), N_grid)
    else:
        frequencies = np.linspace(f_min, f_max, N_grid)
        #freq_to_choose = np.arange(0, K, K/N_grid).astype(int) #choosing proper indices s.t. dataset holds N_grid points
        #frequencies = full_freq[freq_to_choose] #setting only frequencies to be chosen

    if filename is not None:  #doing header if file is empty - nothing otherwise
        if not os.path.isfile(
                filename
        ):  #file doesn't exist: must be created with proper header
            filebuff = open(filename, 'w')
            print("New file ", filename, " created")
            freq_header = np.concatenate((np.zeros(
                (3, )), frequencies, frequencies))
            freq_header = np.reshape(freq_header, (1, len(freq_header)))
            np.savetxt(
                filebuff,
                freq_header,
                header="# row: theta 3 | amp " + str(frequencies.shape[0]) +
                "| ph " + str(frequencies.shape[0]) + "\n# N_grid = " +
                str(N_grid) + " | f_step =" + str(f_step) + " | q_range = " +
                str(q_range) + " | s1_range = " + str(s1_range) +
                " | s2_range = " + str(s2_range),
                newline='\n')
        else:
            filebuff = open(filename, 'a')

    if filename is None:
        amp_dataset = np.zeros(
            (N_data, N_grid))  #allocating storage for returning data
        ph_dataset = np.zeros((N_data, N_grid))
        theta_vector = np.zeros((N_data, 3))

    for i in range(N_data):  #loop on data to be created
        if i % 100 == 0 and i != 0:
            print("Generated WF ", i)

            #setting value for data
        if isinstance(m2_range, tuple):
            m2 = np.random.uniform(m2_range[0], m2_range[1])
        else:
            m2 = m2_range
        if isinstance(q_range, tuple):
            m1 = np.random.uniform(q_range[0], q_range[1]) * m2
        else:
            m1 = q_range * m2
        if isinstance(s1_range, tuple):
            spin1z = np.random.uniform(s1_range[0], s1_range[1])
        else:
            spin1z = s1_range
        if isinstance(s2_range, tuple):
            spin2z = np.random.uniform(s2_range[0], s2_range[1])
        else:
            spin2z = s2_range

            #debug!!!
        if m1 / m2 > 4.6 and (np.abs(spin1z) > 0.8 or np.abs(spin2z) > 0.8):
            continue

            #getting the wave
        hptilde, hctilde = lalsim.SimInspiralChooseFDWaveform(  #where is its definition and documentation????
            m1 * lalsim.lal.MSUN_SI,  #m1
            m2 * lalsim.lal.MSUN_SI,  #m2
            0.,
            0.,
            spin1z,  #spin vector 1
            0.,
            0.,
            spin2z,  #spin vector 2
            d * 1e6 * lalsim.lal.PC_SI,  #distance to source
            0.,  #inclination
            0.,  #phi ref
            0.,  #longAscNodes (for precession)
            0.,  #eccentricity
            0.,  #meanPerAno (for precession)
            f_step,  # frequency incremental step
            f_low,  # lowest value of frequency
            f_high,  # highest value of frequency
            f_low,  #some reference value of frequency (??)
            LALpars,  #some lal dictionary
            approx  #approx method for the model
        )
        h = np.array(hptilde.data.data) + 1j * np.array(
            hctilde.data.data)  #complex waveform
        temp_theta = [m1 / m2, spin1z, spin2z]
        temp_amp = (np.abs(h)[int(f_min / f_step):int(f_max / f_step)].real)
        temp_ph = (np.unwrap(
            np.angle(h))[int(f_min / f_step):int(f_max / f_step)].real)

        #bringing waves on the chosen grid
        temp_amp = np.interp(frequencies, full_freq, temp_amp)
        temp_ph = np.interp(frequencies, full_freq, temp_ph)
        #temp_ph = temp_ph[freq_to_choose]; temp_amp = temp_amp[freq_to_choose] #old version of code

        temp_ph = temp_ph - temp_ph[
            0]  #all frequencies are shifted by a constant to make the wave start at zero phase!!!! IMPORTANT

        #removing spourious gaps (if present)
        (index, ) = np.where(
            temp_amp / temp_amp[0] <
            5e-3)  #there should be a way to choose right threshold...
        if len(index) > 0:
            temp_ph[index] = temp_ph[index[0] - 1]

        if filename is None:
            amp_dataset[
                i, :] = temp_amp  #putting waveform in the dataset to return
            ph_dataset[i, :] = temp_ph  #phase
            theta_vector[i, :] = temp_theta

        if filename is not None:  #saving to file
            to_save = np.concatenate((temp_theta, temp_amp, temp_ph))
            to_save = np.reshape(to_save, (1, len(to_save)))
            np.savetxt(filebuff, to_save)

    if filename is None:
        return theta_vector, amp_dataset.real, ph_dataset.real, frequencies
    else:
        filebuff.close()
        return None
def make_FDwaveform(paramdict):
    """Generate FD waveform from lal.
    Parameters
    ----------
    paramdict: dictionary
        A dictionary with keys for the different
        parameters that go into ChooseFDWaveform
    M : scalar, mass in solar masses
    q : scalar, mass ratio
    chi1,chi2: aligned spins
    approximant_FD: approximant type
    deltaF: frequency spacing
    f_min: starting freq
    f_max: max freq

    Returns
    -------
    f: array.  Array of frequency points
    Hp: h plus array at frequencies in f
    Hc: h cross array at frequencies in f
    """

    # define defaults
    defaultdict = dict()
    defaultdict['m1'] = 10.
    defaultdict['m2'] = 10.
    for key in [
            'phiRef', 'S1x', 'S1y', 'S1z', 'S2x', 'S2y', 'S2z', 'f_ref', 'z',
            'i', 'lambda1', 'lambda2', 'longAscNodes', 'eccentricity',
            'meanPerAno'
    ]:
        defaultdict[key] = 0.0
    for key in ['waveFlags', 'nonGRparams', 'LALpars']:
        defaultdict[key] = None
    defaultdict['r'] = 1e6 * lal.PC_SI
    defaultdict['amplitudeO'] = -1
    defaultdict['phaseO'] = -1
    defaultdict['f_min'] = 40.
    defaultdict['f_max'] = 4098.
    defaultdict['deltaF'] = 0.5
    defaultdict['approximant_FD'] = LS.IMRPhenomD

    # update defaults with what is in paramdict
    for key in paramdict.keys():
        defaultdict[key] = paramdict[key]

    # turn dictionary keys into variable names:
    for k, v in defaultdict.items():
        exec(k + '=v')

    m1_SI = m1 * lal.MSUN_SI
    m2_SI = m2 * lal.MSUN_SI

    try:
        # old call signature for lalsimulation waveforms
        Hp, Hc = LS.SimInspiralChooseFDWaveform(phiRef, deltaF, m1_SI, m2_SI,
                                                S1x, S1y, S1z, S2x, S2y, S2z,
                                                f_min, f_max, f_ref, r, i,
                                                lambda1, lambda2, waveFlags,
                                                nonGRparams, amplitudeO,
                                                phaseO, approximant_FD)
        print 'using old lalsimulation waveform signature'
    except TypeError:
        # newer call signature for lalsimulation waveforms includes parameters for eccentricity
        Hp, Hc = LS.SimInspiralChooseFDWaveform(m1_SI, m2_SI, S1x, S1y, S1z,
                                                S2x, S2y, S2z, r, i, phiRef,
                                                longAscNodes, eccentricity,
                                                meanPerAno, deltaF, f_min,
                                                f_max, f_ref, LALpars,
                                                approximant_FD)

    f = np.arange(Hp.data.length) * deltaF
    n = len(f)
    return f, Hp.data.data, Hc.data.data
Ejemplo n.º 9
0
    def __init__(self, mass1, mass2, S, f_low, approximant, amplitude_order,
                 phase_order):
        """Create a TaylorF2 signal model with the given masses, PSD function
        S(f), PN amplitude order, and low-frequency cutoff."""

        if approximant in (lalsimulation.TaylorF2,
                           lalsimulation.SpinTaylorT4Fourier,
                           lalsimulation.SpinTaylorT2Fourier):
            # Frequency-domain post-Newtonian inspiral waveform.
            h, _ = lalsimulation.SimInspiralChooseFDWaveform(
                phiRef=0,
                deltaF=1,
                m1=mass1 * lal.MSUN_SI,
                m2=mass2 * lal.MSUN_SI,
                S1x=0,
                S1y=0,
                S1z=0,
                S2x=0,
                S2y=0,
                S2z=0,
                f_min=f_low,
                f_max=0,
                f_ref=0,
                r=1e6 * lal.PC_SI,
                i=0,
                lambda1=0,
                lambda2=0,
                waveFlags=None,
                nonGRparams=None,
                amplitudeO=amplitude_order,
                phaseO=0,
                approximant=approximant)

            # Find indices of first and last nonzero samples.
            nonzero = np.nonzero(h.data.data)[0]
            first_nonzero = nonzero[0]
            last_nonzero = nonzero[-1]
        elif approximant == lalsimulation.TaylorT4:
            # Time-domain post-Newtonian inspiral waveform.
            hplus, hcross = lalsimulation.SimInspiralChooseTDWaveform(
                phiRef=0,
                deltaT=1 / 4096,
                m1=mass1 * lal.MSUN_SI,
                m2=mass2 * lal.MSUN_SI,
                s1x=0,
                s1y=0,
                s1z=0,
                s2x=0,
                s2y=0,
                s2z=0,
                f_min=f_low,
                f_ref=f_low,
                r=1e6 * lal.PC_SI,
                i=0,
                lambda1=0,
                lambda2=0,
                waveFlags=None,
                nonGRparams=None,
                amplitudeO=amplitude_order,
                phaseO=phase_order,
                approximant=approximant)

            hplus.data.data += hcross.data.data
            hplus.data.data /= np.sqrt(2)

            h = lal.CreateCOMPLEX16FrequencySeries(
                None, lal.LIGOTimeGPS(0), 0, 0, lal.DimensionlessUnit,
                len(hplus.data.data) // 2 + 1)
            plan = CreateForwardREAL8FFTPlan(len(hplus.data.data), 0)
            lal.REAL8TimeFreqFFT(h, hplus, plan)

            f = h.f0 + len(h.data.data) * h.deltaF
            first_nonzero = long(np.floor((f_low - h.f0) / h.deltaF))
            last_nonzero = long(np.ceil((2048 - h.f0) / h.deltaF))
            last_nonzero = min(last_nonzero, len(h.data.data) - 1)
        else:
            raise ValueError("unrecognized approximant")

        # Frequency sample points
        self.dw = 2 * np.pi * h.deltaF
        f = h.f0 + h.deltaF * np.arange(first_nonzero, last_nonzero + 1)
        self.w = 2 * np.pi * f

        # Throw away leading and trailing zeros.
        h = h.data.data[first_nonzero:last_nonzero + 1]

        self.denom_integrand = 4 / (2 * np.pi) * (np.square(h.real) +
                                                  np.square(h.imag)) / S(f)
        self.den = np.trapz(self.denom_integrand, dx=self.dw)
    duration = lalsimulation.SimInspiralTaylorF2ReducedSpinChirpTime(
        10, mass1*lal.MSUN_SI, mass2*lal.MSUN_SI, 0,
        lalsimulation.PNORDER_THREE_POINT_FIVE)
    duration = int(np.ceil(filter.ceil_pow_2(duration)))
    sample_rate = 16384
    nsamples = duration * sample_rate
    nsamples_fft = nsamples//2 + 1
    af = lal.CreateCOMPLEX16Vector(nsamples)
    f = np.arange(nsamples) / duration

    hplus, hcross = lalsimulation.SimInspiralChooseFDWaveform(
        0, 1/duration,
        mass1*lal.MSUN_SI, mass2*lal.MSUN_SI,
        0, 0, 0, 0, 0, 0,
        9, 0, 40,
        500 * lal.PC_SI, 0, 0, 0,
        None, None,
        lalsimulation.PNORDER_THREE_POINT_FIVE,
        lalsimulation.PNORDER_NEWTONIAN, lalsimulation.TaylorF2)

    af.data[:len(hplus.data.data)] = abs2(hplus.data.data + 1j * hcross.data.data)
    af.data[len(hplus.data.data):] = 0
    af.data[0] = 0
    af.data[1:len(hplus.data.data)] /= S(f[1:len(hplus.data.data)])

    a = lal.CreateCOMPLEX16Vector(nsamples)
    plan = lal.CreateReverseCOMPLEX16FFTPlan(nsamples, 0)
    lal.COMPLEX16VectorFFT(a, af, plan)

    a = a.data
Ejemplo n.º 11
0
def autocorrelation(mass1, mass2, S, f_low, out_duration, approximant,
                    amplitude_order, phase_order):
    """
    Calculate the complex autocorrelation sequence a(t), for t >= 0, of an
    inspiral signal.

    Parameters
    ----------
    mass1 : float
        Mass of component 1 (solar masses).
    mass2 : float
        Mass of component 1 (solar masses).
    S : callable
        Noise power spectral density function.
    f_low : float
        Low frequency cutoff (Hz).
    out_duration : float
        Compute the autocorrelation function from time t=0 to t=output_duration.
    approximant : int
        Post-Newtonian approximant (e.g. lalsimulation.TaylorF2).
    amplitude_order : int
        Twice the post-Newtonian amplitude order (e.g. 3).
    phase_order : int
        Twice the post-Newtonian phase order (e.g. 3).

    Returns
    -------
    acor : `numpy.ndarray`
        The complex-valued autocorrelation sequence.
    sample_rate : float
        Sample rate in Hz.
    """

    # Compute duration of template, rounded up to a power of 2.
    duration = ceil_pow_2(
        lalsimulation.SimInspiralTaylorF2ReducedSpinChirpTime(
            f_low, mass1 * lal.MSUN_SI, mass2 * lal.MSUN_SI, 0, phase_order))

    # Evaluate waveform. Terminates at ISCO.
    hplus, hcross = lalsimulation.SimInspiralChooseFDWaveform(
        0, 1 / duration, mass1 * lal.MSUN_SI, mass2 * lal.MSUN_SI, 0, 0, 0, 0,
        0, 0, f_low, 0, 0, 1e6 * lal.PC_SI, 0, 0, 0, None, None,
        amplitude_order, phase_order, approximant)

    # Force `plus' and `cross' waveform to be in quadrature.
    h = 0.5 * (hplus.data.data + 1j * hcross.data.data)

    # Determine length of IFFT; round up to a power of 2.
    nsamples = 2 * int(ceil_pow_2(len(h)))

    # Compute autopower spectral density.
    power = np.empty(nsamples, dtype=hplus.data.data.dtype)
    power[0] = 0
    f = np.arange(1, len(h)) / duration
    power[1:len(h)] = abs2(h[1:]) / S(f)
    power[len(h):] = 0

    sample_rate = nsamples / duration

    # Determine length of output FFT.
    nsamples_out = int(np.ceil(out_duration * sample_rate))

    acor = truncated_ifft(power, nsamples_out)
    acor /= np.abs(acor[0])

    # If we have done this right, then the zeroth sample represents lag 0
    assert np.argmax(np.abs(acor)) == 0
    assert np.isreal(acor[0])

    # Done!
    return acor, float(sample_rate)
Ejemplo n.º 12
0
def gen_waveform(freq, z=0, omega=OMEGA, **params):
    """Generate frequency-domain inspiral waveform

    `freq` should be an array of frequency points at which the
    waveform should be interpolated.  Returns a tuple of
    (h_tilde^plus, h_tilde^cross) real-valued (amplitude only) arrays.

    The waveform is generated with
    lalsimulation.SimInspiralChooseFDWaveform().  Keyword arguments
    are used to update the default waveform parameters (1.4/1.4
    Msolar, optimally-oriented, 100 Mpc, (see DEFAULT_PARAMS macro)).
    The mass parameters ('m1' and 'm2') should be specified in solar
    masses and the 'distance' parameter should be specified in
    parsecs**.  Waveform approximants may be given as string names
    (see `lalsimulation` documentation for more info).  If the
    approximant is not specified explicitly, DEFAULT_APPROXIMANT_BNS
    waveform will be used if either mass is less than 5 Msolar and
    DEFAULT_APPROXIMANT_BBH waveform will be used otherwise.

    If a redshift `z` is specified (with optional `omega`), it's
    equivalent distance will be used (ignoring any `distance`
    parameter provided) and the masses will be redshift-corrected
    appropriately.  Otherwise no mass redshift correction will be
    applied.

    For example, to generate a 20/20 Msolar BBH waveform:

    >>> hp,hc = waveform.gen_waveform(freq, 'm1'=20, 'm2'=20)

    **NOTE: The requirement that masses are specified in solar masses
    and distances are specified in parsecs is different than that of
    the underlying lalsimulation method which expects mass and
    distance parameters to be in SI units.

    """
    iparams = _get_waveform_params(**params)

    # if redshift specified use that as distance and correct
    # appropriately, ignoring any distance specified in params.
    if z != 0:
        iparams['distance'] = lal.LuminosityDistance(omega, z) * 1e6
        iparams['m1'] *= 1.0 + z
        iparams['m2'] *= 1.0 + z

    # convert to SI units
    iparams['distance'] *= lal.PC_SI
    iparams['m1'] *= lal.MSUN_SI
    iparams['m2'] *= lal.MSUN_SI
    iparams['approximant'] = lalsimulation.SimInspiralGetApproximantFromString(
        iparams['approximant'])

    iparams['deltaF'] = freq[1] - freq[0]
    iparams['f_min'] = freq[0]
    # FIXME: the max frequency in the generated waveform is not always
    # greater than f_max, so as a workaround we generate over the full
    # band.  Probably room for speedup here
    # iparams['f_max'] = freq[-1]
    iparams['f_max'] = 10000
    # print(iparams)

    # logging.debug('waveform params = {}'.format(iparams))

    # generate waveform
    h = lalsimulation.SimInspiralChooseFDWaveform(**iparams)
    # print(h)

    freq_h = h[0].f0 + np.arange(len(h[0].data.data)) * h[0].deltaF

    def interph(h):
        "interpolate amplitude of h array"
        # FIXME: this only interpolates/returns the amplitude, and not
        # the full complex data (throws out phase), because this was
        # not working:
        # hir = scipy.interpolate.interp1d(freq_h, np.real(h.data.data))(freq)
        # hii = scipy.interpolate.interp1d(freq_h, np.imag(h.data.data))(freq)
        # return hir + 1j * hii
        return scipy.interpolate.interp1d(freq_h,
                                          np.absolute(h.data.data))(freq)

    hi = map(interph, h)

    return hi
Ejemplo n.º 13
0
def make_FDwaveform(M,
                    q,
                    chi1,
                    chi2,
                    approximant_FD,
                    deltaF=0.5,
                    f_min=10,
                    f_max=4096):
    """Generate FD waveform from lal.
    Parameters
    ----------
    M : scalar, mass in solar masses
    q : scalar, mass ratio
    chi1,chi2: aligned spins
    approximant_FD: approximant type
    deltaF: frequency spacing
    f_min: starting freq
    f_max: max freq

    Returns
    -------
    [frequency array, H plus]
    """

    m1 = M * 1.0 / (1.0 + q)
    m2 = M * q / (1.0 + q)
    phiRef = 0.0
    m1_SI = m1 * lal.MSUN_SI
    m2_SI = m2 * lal.MSUN_SI
    S1x = 0.0
    S1y = 0.0
    S1z = chi1
    S2x = 0.0
    S2y = 0.0
    S2z = chi2
    f_ref = 0.0
    r = 1e6 * lal.PC_SI
    z = 0.0
    i = 0.0
    lambda1 = 0.0
    lambda2 = 0.0
    waveFlags = None
    nonGRparams = None
    amplitudeO = -1
    phaseO = -1
    #    try:
    #        # old call signature for lalsimulation waveforms
    #        Hp, Hc = LS.SimInspiralChooseFDWaveform(phiRef, deltaF, m1_SI, m2_SI, S1x, S1y, S1z, S2x, S2y, S2z,
    #          f_min, f_max, f_ref, r, i, lambda1, lambda2, waveFlags, nonGRparams, amplitudeO, phaseO,
    #          approximant_FD)
    #        print 'using old lalsimulation waveform signature'
    #    except TypeError:
    #        # newer call signature for lalsimulation waveforms includes parameters for eccentricity
    #        longAscNodes, eccentricity, meanPerAno = 0.0, 0.0, 0.0
    #        # If we need extra parameters put them into the Dict; I assume we don't need anything special
    #        LALpars = None
    #        phaseO = None
    #        Hp, Hc = LS.SimInspiralChooseFDWaveform(m1_SI, m2_SI,
    #                                                S1x, S1y, S1z, S2x, S2y, S2z,
    #                                                r, i, phiRef,
    #                                                longAscNodes, eccentricity, meanPerAno,
    #                                                deltaF, f_min, f_max, f_ref,
    #                                                LALpars,
    #                                                approximant_FD)
    #
    Hp, Hc = LS.SimInspiralChooseFDWaveform(phiRef, deltaF, m1_SI, m2_SI, S1x,
                                            S1y, S1z, S2x, S2y, S2z, f_min,
                                            f_max, f_ref, r, i, lambda1,
                                            lambda2, waveFlags, nonGRparams,
                                            amplitudeO, phaseO, approximant_FD)

    f = np.arange(Hp.data.length) * deltaF
    n = len(f)
    return [f, Hp.data.data]
Ejemplo n.º 14
0
LALpars = lal.CreateDict()
approx = lalsim.SimInspiralGetApproximantFromString('IMRPhenomD')

print(approx)

hptilde, hctilde = lalsim.SimInspiralChooseFDWaveform(
    m1 * lalsim.lal.MSUN_SI,
    m2 * lalsim.lal.MSUN_SI,
    0,
    0,
    spin1z,
    0,
    0,
    spin2z,
    d * 1e6 * lalsim.lal.PC_SI,
    0,
    0,
    0,  #longAscNodes
    0,  #eccentricity
    0,  #meanPerAno
    1 / 16,
    10,
    2048,
    #4096,
    30,
    LALpars,
    approx)

print(hptilde.data.data.shape, (2048) / 0.1)

hptilde2, hctilde2 = lalsim.SimInspiralChooseFDWaveform(
    m1 * lalsim.lal.MSUN_SI,
Ejemplo n.º 15
0
def test_taylorf2_array():

    cl_context, cl_device, cl_queue = bagwacl_init()

    tf2_kernels, BAGWACLTaylorF2Params_new, _ = taylorf2.init_kernels(
        cl_context, cl_device)

    ## generate multiple waveforms and test each one against LAL/CPU code...
    nwaveforms = 100
    params = []
    h_vecarray_cpu = []

    # Other IFO data params
    psdstart = 0
    psdlength = 120000
    trigtime = 6000
    seglen = 10.
    srate = 4096.

    cbc_params_lst = []

    for i in xrange(nwaveforms):
        cbc_params = lalsupport.sample_cbc_params_from_prior()
        cbc_params_lst.append(cbc_params)
        li_cbc_params = lalsupport.create_livariables_from_cbc_params(
            cbc_params)

        params.append(BAGWACLTaylorF2Params_new())

        (fStart, fEnd, deltaF) = t2_wfm_params_init(seglen, srate)

        #(phic,deltaF,m1_SI,m2_SI,S1z,S2z,fStart,fEnd,distance_SI,lambda1,lambda2,spinO,tidalO,phaseO,amplitudeO)=generate_random_wfm_params()

        taylorf2.tf2_pn_params_init(
            params[i],
            cbc_params.phase,
            deltaF,
            cbc_params.mass1 * LAL_MSUN_SI,
            cbc_params.mass2 * LAL_MSUN_SI,
            cbc_params.S1z,
            cbc_params.S2z,
            fStart,
            fEnd,
            cbc_params.distance * LAL_PC_SI * 1e6,
            cbc_params.lambda1,
            cbc_params.lambda2,
            cbc_params.spinO,
            cbc_params.tidalO,
            cbc_params.LAL_PNORDER,
            cbc_params.LAL_AMPORDER,
        )

        # Fake some interferometer data
        #ifos=[
        #['H1','LALSimAdLIGO',fStart,'DUMMY'],
        #]

        #data=lalsupport.generate_ifoData(
        #ifos,
        #psdstart,
        #psdlength,
        #seglen,
        #trigtime,
        #srate=4096.,
        #)

        #lalsupport.init_ifoData(data)

        #data.modelParams=li_cbc_params

        # Call equivalent LALSimulation/Inference CPU-only function
        #lalinference.TemplateXLALSimInspiralChooseWaveform(data)

        waveFlags = lalsimulation.SimInspiralCreateWaveformFlags()
        lalsimulation.SimInspiralSetSpinOrder(
            waveFlags, lalsimulation.LAL_SIM_INSPIRAL_SPINLESS)
        lalsimulation.SimInspiralSetTidalOrder(
            waveFlags, lalsimulation.LAL_SIM_INSPIRAL_TIDAL_ORDER_0PN)

        h_vec_cpu, _ = lalsimulation.SimInspiralChooseFDWaveform(
            cbc_params.phase,
            deltaF,
            cbc_params.mass1 * LAL_MSUN_SI,
            cbc_params.mass2 * LAL_MSUN_SI,
            cbc_params.S1x,
            cbc_params.S1y,
            cbc_params.S1z,
            cbc_params.S2x,
            cbc_params.S2y,
            cbc_params.S2z,
            fStart,
            fEnd,
            cbc_params.distance * LAL_PC_SI * 1e6,
            cbc_params.inclination,
            cbc_params.lambda1,
            cbc_params.lambda2,
            waveFlags,
            None,
            cbc_params.LAL_AMPORDER,
            cbc_params.LAL_PNORDER,
            cbc_params.LAL_APPROXIMANT,
        )

        # Extract output complex strain vector from LALSimulation output
        h_vecarray_cpu.append(h_vec_cpu.data.data)

    length = int(params[0]['n'][0])

    params = np.array(params, dtype=params[0].dtype)

    mem_pool = cl_tools.MemoryPool(
        cl_tools.ImmediateAllocator(cl_queue, cl.mem_flags.READ_ONLY))
    params_cl = cl.array.to_device(cl_queue, params)

    hTilde_vecarray_cl = cl.array.zeros(cl_queue, (length * nwaveforms),
                                        np.complex128)

    tf2_kernels.BAGWACLTaylorF2threePointFivePN_array.set_scalar_arg_dtypes([
        None,
        None,
        np.int32,
    ])

    tf2_kernels.BAGWACLTaylorF2threePointFivePN_array(
        cl_queue,
        (
            length,
            nwaveforms,
        ),
        None,
        hTilde_vecarray_cl.data,
        params_cl.data,
        np.int32(0),
    )

    h_vecarray_gpu = hTilde_vecarray_cl.get()
    np.savetxt(
        'htilde_gpu.dat',
        lalsupport.convert_bagwacl_templates_to_lal_templates(
            h_vecarray_gpu[0:length], cbc_params_lst[-1].inclination)[0])
    np.savetxt('htilde_cpu.dat', h_vecarray_cpu[0])

    failure_count = 0

    for i, h_vec_cpu in enumerate(h_vecarray_cpu):
        h_vec_gpu, _ = lalsupport.convert_bagwacl_templates_to_lal_templates(
            h_vecarray_gpu[i * length:(i + 1) * length],
            cbc_params_lst[0].inclination)
        try:
            assert np.allclose(h_vec_cpu, h_vec_gpu, atol=0., rtol=1e-6)
        except AssertionError:
            failure_count += 1

    print "Failure count is", failure_count
Ejemplo n.º 16
0
def get_waveform(approximant,
                 phase_order,
                 amplitude_order,
                 spin_order,
                 template_params,
                 start_frequency,
                 sample_rate,
                 length,
                 datafile=None,
                 verbose=False):
    #{{{
    print("IN hERE")
    delta_t = 1. / sample_rate
    delta_f = 1. / length
    filter_N = int(length)
    filter_n = filter_N / 2 + 1
    if approximant in fd_approximants() and 'Eccentric' not in approximant:
        print("NORMAL FD WAVEFORM for", approximant)
        delta_f = sample_rate / length
        hplus, hcross = get_fd_waveform(template_params,
                                        approximant=approximant,
                                        spin_order=spin_order,
                                        phase_order=phase_order,
                                        delta_f=delta_f,
                                        f_lower=start_frequency,
                                        amplitude_order=amplitude_order)
    elif approximant in td_approximants() and 'Eccentric' not in approximant:
        print("NORMAL TD WAVEFORM for", approximant)
        hplus, hcross = get_td_waveform(template_params,
                                        approximant=approximant,
                                        spin_order=spin_order,
                                        phase_order=phase_order,
                                        delta_t=1.0 / sample_rate,
                                        f_lower=start_frequency,
                                        amplitude_order=amplitude_order)
    elif 'EccentricIMR' in approximant:
        #{{{
        # Legacy support
        import sys
        sys.path.append('/home/kuma/grav/kuma/src/Eccentric_IMR/Codes/Python/')
        import EccentricIMR as Ecc
        try:
            mass1 = getattr(template_params, 'mass1')
            mass2 = getattr(template_params, 'mass2')
        except:
            raise RuntimeError("template_params does not have mass1 or mass2!")
        try:
            ecc = getattr(template_params, 'alpha1')
            if 'E0' in approximant: ecc = 0
            anom = getattr(template_params, 'alpha2')
            inc = getattr(template_params, 'inclination')
            rtrans = getattr(template_params, 'alpha')
            beta = 0
        except:
            raise RuntimeError(\
                  "template_params does not have alpha{,1,2} or inclination")
        tol = 1.e-16
        fmin = start_frequency
        sample_rate = sample_rate
        #
        print(" Using phase order: %d" % phase_order, file=sys.stdout)
        sys.stdout.flush()
        hplus, hcross = Ecc.generate_eccentric_waveform(mass1, mass2,\
                            ecc, anom, inc, beta,\
                            tol,\
                            r_transition=rtrans,\
                            phase_order=phase_order,\
                            fmin=fmin,\
                            sample_rate=sample_rate,\
                            inspiral_only=False)
        #}}}
    elif 'EccentricInspiral' in approximant:
        #{{{
        # Legacy support
        import sys
        sys.path.append('/home/kuma/grav/kuma/src/Eccentric_IMR/Codes/Python/')
        import EccentricIMR as Ecc
        try:
            mass1 = getattr(template_params, 'mass1')
            mass2 = getattr(template_params, 'mass2')
        except:
            raise RuntimeError("template_params does not have mass1 or mass2!")
        try:
            ecc = getattr(template_params, 'alpha1')
            if 'E0' in approximant: ecc = 0
            anom = getattr(template_params, 'alpha2')
            inc = getattr(template_params, 'inclination')
            beta = getattr(template_params, 'alpha')
        except:
            raise RuntimeError(\
                  "template_params does not have alpha{,1,2} or inclination")
        tol = 1.e-16
        fmin = start_frequency
        sample_rate = sample_rate
        #
        hplus, hcross = Ecc.generate_eccentric_waveform(mass1, mass2,\
                            ecc, anom, inc, beta,\
                            tol,\
                            phase_order=phase_order,\
                            fmin=fmin,\
                            sample_rate=sample_rate,\
                            inspiral_only=True)
        #}}}
    elif 'EccentricFD' in approximant:
        #{{{
        # Legacy support
        import lalsimulation as ls
        import lal
        delta_f = sample_rate / length
        try:
            mass1 = getattr(template_params, 'mass1')
            mass2 = getattr(template_params, 'mass2')
        except:
            raise RuntimeError("template_params does not have mass1 or mass2!")
        try:
            ecc = getattr(template_params, 'alpha1')
            if 'E0' in approximant: ecc = 0
            anom = getattr(template_params, 'alpha2')
            inc = getattr(template_params, 'inclination')
        except:
            raise RuntimeError(\
                  "template_params does not have alpha{1,2} or inclination")
        eccPar = ls.SimInspiralCreateTestGRParam("inclination_azimuth", inc)
        ls.SimInspiralAddTestGRParam(eccPar, "e_min", ecc)
        fmin = start_frequency
        fmax = sample_rate / 2
        #
        thp, thc = ls.SimInspiralChooseFDWaveform(0, delta_f,\
                        mass1*lal.MSUN_SI, mass2*lal.MSUN_SI,\
                        0,0,0,0,0,0,\
                        fmin, fmax, 0, 1.e6 * lal.PC_SI,\
                        inc, 0, 0, None, eccPar, -1, 7, ls.EccentricFD)
        hplus = FrequencySeries(thp.data.data[:],
                                delta_f=thp.deltaF,
                                epoch=thp.epoch)
        hcross = FrequencySeries(thc.data.data[:],
                                 delta_f=thc.deltaF,
                                 epoch=thc.epoch)
        #}}}
    elif 'FromDataFile' in approximant:
        #{{{
        # Legacy support
        if not os.path.exists(datafile):
            raise IOError("File %s not found!" % datafile)
        if verbose:
            print("Reading from data file %s" % datafile)

        # Figure out waveform parameters from filename
        #q_value, M_value, w_value, _, _ = EA.get_q_m_e_pn_o_from_filename(datafile)
        q_value, M_value, w_value = EA.get_q_m_e_from_filename(datafile)

        # Read data, down-sample (assume data file is more finely sampled than
        # needed, i.e. interpolation is NOT supported, nor will be)
        data = np.loadtxt(datafile)
        dt = data[1, 0] - data[0, 0]
        delta_t = 1. / sample_rate
        downsample_ratio = delta_t / dt
        if not approx_equal(downsample_ratio, np.int(downsample_ratio)):
            raise RuntimeError(
                "Cannot handling resampling at a fractional factor = %e" %
                downsample_ratio)
        elif verbose:
            print("Downsampling by a factor of %d" % int(downsample_ratio))
        h_real = TimeSeries(data[::int(downsample_ratio), 1] / DYN_RANGE_FAC,
                            delta_t=delta_t)
        h_imag = TimeSeries(data[::int(downsample_ratio), 2] / DYN_RANGE_FAC,
                            delta_t=delta_t)

        if verbose:
            print("max, min,len of h_real = ", max(h_real.data),
                  min(h_real.data), len(h_real.data))

        # Compute Strain
        tmplt_pars = template_params
        wav = generate_detector_strain(tmplt_pars, h_real, h_imag)
        wav = extend_waveform_TimeSeries(wav, filter_N)

        # Return TimeSeries with (m1, m2, w_value)
        m1, m2 = mtotal_eta_to_mass1_mass2(M_value,
                                           q_value / (1. + q_value)**2)
        htilde = make_frequency_series(wav)
        htilde = extend_waveform_FrequencySeries(htilde, filter_n)

        if verbose:
            print("ISNAN(htilde from file) = ", np.any(np.isnan(htilde.data)))
        return htilde, [m1, m2, w_value, dt]
        #}}}
    else:
        raise IOError(".. APPROXIMANT %s not found.." % approximant)
    ##
    hvec = hplus
    htilde = make_frequency_series(hvec)
    htilde = extend_waveform_FrequencySeries(htilde, filter_n)
    #
    print("type of hplus, hcross = ", type(hplus.data), type(hcross.data))
    if any(isnan(hplus.data)) or any(isnan(hcross.data)):
        print("..### %s hplus or hcross have NANS!!" % approximant)
    #
    if any(isinf(hplus.data)) or any(isinf(hcross.data)):
        print("..### %s hplus or hcross have INFS!!" % approximant)
    #
    if any(isnan(htilde.data)):
        print("..### %s Fourier transform htilde has NANS!!" % approximant)
    #
    if any(isinf(htilde.data)):
        print("..### %s Fourier transform htilde has INFS!!" % approximant)
    #
    return htilde
Ejemplo n.º 17
0
m2 = m2v * LS.lal.MSUN_SI

# In[3]:

nongrParams = lal.CreateDict()

hPlus, hCross = LS.SimInspiralChooseFDWaveform(m1=m1,
                                               m2=m2,
                                               S1x=S1x,
                                               S1y=S1y,
                                               S1z=S1z,
                                               S2x=S2x,
                                               S2y=S2y,
                                               S2z=S2z,
                                               distance=r,
                                               inclination=i,
                                               phiRef=phi0,
                                               longAscNodes=0.,
                                               eccentricity=0.,
                                               meanPerAno=0.,
                                               deltaF=deltaF,
                                               f_min=f_min,
                                               f_max=f_max,
                                               f_ref=f_ref,
                                               LALpars=nongrParams,
                                               approximant=approximant)

f = hPlus.deltaF * np.arange(len(hPlus.data.data)) + hPlus.f0
h = hPlus.data.data + (1j) * hCross.data.data

print(hPlus.data.data, hCross.data.data)
Ejemplo n.º 18
0
def least_match_quadratic_waveform_unnormalized(paramspoints, known_quad_bases,
                                                npts, distance, deltaF, f_min,
                                                f_max, waveFlags, approximant):
    overlaps = numpy.zeros(npts)
    modula = numpy.zeros(npts)
    for i in numpy.arange(0, len(paramspoints)):
        paramspoint = paramspoints[i]
        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
        hp_quad_tmp = (numpy.absolute(hp_tmp))**2
        residual = hp_quad_tmp
        for k in numpy.arange(0, len(known_quad_bases)):
            residual -= proj(known_quad_bases[k], hp_quad_tmp)
        modula[i] = numpy.sqrt(numpy.vdot(residual, residual))
    arg_newbasis = numpy.argmax(modula)
    mass1, mass2 = get_m1m2_from_mcq(paramspoints[arg_newbasis][0],
                                     paramspoints[arg_newbasis][1])
    mass1 *= lal.lal.MSUN_SI
    mass2 *= lal.lal.MSUN_SI
    sp1x, sp1y, sp1z = spherical_to_cartesian(paramspoints[arg_newbasis, 2:5])
    sp2x, sp2y, sp2z = spherical_to_cartesian(paramspoints[arg_newbasis, 5:8])
    inclination = paramspoints[arg_newbasis][8]
    phi_ref = paramspoints[arg_newbasis][9]
    ecc = 0
    if len(paramspoint) == 11:
        ecc = paramspoints[arg_newbasis][10]
    if len(paramspoint) == 12:
        lambda1 = paramspoints[arg_newbasis][10]
        lambda2 = paramspoints[arg_newbasis][11]
        lalsimulation.SimInspiralWaveformParamsInsertTidalLambda1(
            waveFlags, lambda1)
        lalsimulation.SimInspiralWaveformParamsInsertTidalLambda2(
            waveFlags, lambda2)
    [plus_new, cross_new] = lalsimulation.SimInspiralChooseFDWaveform(
        mass1, mass2, sp1x, sp1y, sp1z, sp2x, sp2y, sp2z, distance,
        inclination, phi_ref, 0, ecc, 0, deltaF, f_min, f_max, 0, waveFlags,
        approximant)
    hp_new = plus_new.data.data
    hp_new = hp_new[numpy.int(f_min / deltaF):numpy.int(f_max / deltaF)]
    hp_quad_new = (numpy.absolute(hp_new))**2
    basis_quad_new = gram_schmidt(known_quad_bases, hp_quad_new)
    return numpy.array(
        [basis_quad_new, paramspoints[arg_newbasis],
         modula[arg_newbasis]])  # elements, masses&spins, residual mod
Ejemplo n.º 19
0
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}
Ejemplo n.º 20
0
def Get_LALSuite_Waveform(source, waveform_dict, out_frame="observer"):
    """Gets the frequency domain waveform of a particular source using a waveform modelled in
    LIGO's ``lalsuite`` package. The source is given plus and cross
    properties with their phase and amplitude for user convenience.

    Parameters
    ----------
    source: object
            source object from ``binary``, contains all source parameters
    waveform_dict: dictionary
            The dictionary is comprised of necessities for the ``SimInspiralChooseFDWaveform`` call in ``lalsimulation`` comprised of:
            ``m1``    mass of companion 1 (kg)
            ``m2``    mass of companion 2 (kg)
            ``S1x``    x-component of the dimensionless spin of object 1
            ``S1y``    y-component of the dimensionless spin of object 1
            ``S1z``    z-component of the dimensionless spin of object 1
            ``S2x``    x-component of the dimensionless spin of object 2
            ``S2y``    y-component of the dimensionless spin of object 2
            ``S2z``    z-component of the dimensionless spin of object 2
            ``distance``    distance of source (m)
            ``inclination``    inclination of source (rad)
            ``phiRef``    reference orbital phase (rad)
            ``longAscNodes``    longitude of ascending nodes, degenerate with the polarization angle, Omega in documentation
            ``eccentricity``    eccentricity at reference epoch
            ``meanPerAno``    mean anomaly of periastron
            ``deltaF``    sampling interval (Hz)
            ``f_min``    starting GW frequency (Hz)
            ``f_max``    ending GW frequency (Hz)
            ``f_ref``    Reference frequency (Hz)
            ``LALparams``    LAL dictionary containing accessory parameters
            ``approximant``    post-Newtonian approximant to use for waveform production
    out_frame: str, {'observer','source'}
        Determines whether the returned frequency is in the source or observer frame.
    """
    h_f_plus, h_f_cross = lalsimulation.SimInspiralChooseFDWaveform(**waveform_dict)
    h_f_plus_amp, h_f_plus_phase = Get_Amp_Phase(h_f_plus.data.data)
    h_f_cross_amp, h_f_cross_phase = Get_Amp_Phase(h_f_cross.data.data)

    source.h_f_plus_amp = h_f_plus_amp
    source.h_f_plus_phase = h_f_plus_phase
    source.h_f_cross_amp = h_f_cross_amp
    source.h_f_cross_phase = h_f_cross_phase

    full_amp = Get_Full_Amp(h_f_plus_amp, h_f_cross_amp)
    # Need to trim because SimInspiralChooseFDWaveform returns nans and zeros outside of ranges (f_min,f_cutoff)
    trimmed_full_amp = []
    for amp in full_amp:
        if not np.isnan(amp) and amp != 0.0:
            trimmed_full_amp.append(amp)
    trimmed_full_amp = np.asarray(trimmed_full_amp)
    lin_freqs = np.arange(0, waveform_dict["f_max"], waveform_dict["deltaF"])
    trimmed_freqs = lin_freqs[1 : trimmed_full_amp.shape[0] + 1]

    # The difference between the two is `gwent` has a factor of :math:`\sqrt{\frac{1}{24}}(1+z)^{2}`
    # and `LALSuite` has a factor of :math:`2\sqrt{\frac{1}{64}}`.
    # Thus, :math:`h_{\mathrm{gwent}} = \sqrt{\frac{2}{3}}(1+z)^{2}h_{\mathrm{LAL}}`,
    # this factor is reduced by :math:`\sqrt{\frac{1}{2}}` if using the cross and plus polarizations to get the total Fourier strain amplitude.

    if out_frame == "observer":
        # frequency and strain of source in detector frame and physical units: Hertz and raw Fourier strain amplitude (1/Hertz)
        freqs = trimmed_freqs / (1 + source.z) * u.Hz
        strain = np.sqrt(1 / 3) * (1 + source.z) ** 2 * trimmed_full_amp / u.Hz
    elif out_frame == "source":
        # frequency and strain of source in source frame and physical units: Hertz and raw Fourier strain amplitude (1/Hertz)
        freqs = trimmed_freqs * u.Hz
        strain = np.sqrt(1 / 3) * trimmed_full_amp / u.Hz
    else:
        raise ValueError("The reference frame can only be observer or source.")

    return [freqs, strain]
Ejemplo n.º 21
0
def generate_template(mass1, mass2, S, f_low, sample_rate, template_duration,
                      approximant, amplitude_order, phase_order):
    template_length = sample_rate * template_duration
    if approximant == lalsimulation.TaylorF2:
        zf, _ = lalsimulation.SimInspiralChooseFDWaveform(
            0, 1 / template_duration,
            mass1 * lal.MSUN_SI, mass2 * lal.MSUN_SI,
            0, 0, 0, 0, 0, 0, f_low, 0, 0, 1e6 * lal.PC_SI,
            0, 0, 0, None, None, amplitude_order, phase_order, approximant)
        lal.ResizeCOMPLEX16FrequencySeries(zf, 0, template_length // 2 + 1)

        # Generate over-whitened template
        psd = lal.CreateREAL8FrequencySeries(
            None, zf.epoch, zf.f0, zf.deltaF,
            lal.DimensionlessUnit, len(zf.data.data))
        psd.data.data = S(abscissa(psd))
        zW = matched_filter_spa(zf, psd)
    elif approximant == lalsimulation.TaylorT4:
        hplus, hcross = lalsimulation.SimInspiralChooseTDWaveform(
            0, 1 / sample_rate,
            mass1 * lal.MSUN_SI, mass2 * lal.MSUN_SI,
            0, 0, 0, 0, 0, 0,
            f_low, f_low,
            1e6 * lal.PC_SI,
            0, 0, 0,
            None, None,
            amplitude_order,
            phase_order,
            approximant)

        ht = lal.CreateREAL8TimeSeries(
            None, lal.LIGOTimeGPS(-template_duration), hplus.f0, hplus.deltaT,
            hplus.sampleUnits, template_length)
        hf = lal.CreateCOMPLEX16FrequencySeries(
            None, lal.LIGOTimeGPS(0), 0, 0, lal.DimensionlessUnit,
            template_length // 2 + 1)
        plan = CreateForwardREAL8FFTPlan(template_length, 0)

        ht.data.data[:-len(hplus.data.data)] = 0
        ht.data.data[-len(hplus.data.data):] = hplus.data.data
        lal.REAL8TimeFreqFFT(hf, ht, plan)

        psd = lal.CreateREAL8FrequencySeries(
            None, hf.epoch, hf.f0, hf.deltaF,
            lal.DimensionlessUnit, len(hf.data.data))
        psd.data.data = S(abscissa(psd))

        zWreal = matched_filter_real(hf, psd)

        ht.data.data[:-len(hcross.data.data)] = 0
        ht.data.data[-len(hcross.data.data):] = hcross.data.data

        lal.REAL8TimeFreqFFT(hf, ht, plan)
        zWimag = matched_filter_real(hf, psd)

        zW = lal.CreateCOMPLEX16TimeSeries(
            None, zWreal.epoch, zWreal.f0, zWreal.deltaT, zWreal.sampleUnits,
            len(zWreal.data.data))
        zW.data.data = zWreal.data.data + zWimag.data.data * 1j
    else:
        raise ValueError("unrecognized approximant")
    return (zW.data.data[::-1].conj() * np.sqrt(2)
            * template_duration / sample_rate / 2)
Ejemplo n.º 22
0
def lalsim_fd_waveform(long_asc_nodes=0.0,
                       eccentricity=0.0,
                       mean_per_ano=0.0,
                       phi_ref=0.0,
                       f_ref=None,
                       phase_order=-1,
                       amplitude_order=-1,
                       spin_order=-1,
                       tidal_order=-1,
                       quad1=None,
                       quad2=None,
                       **p):
    """Wrapper for lalsimulation.SimInspiralChooseTDWaveform.
    Simplified version of pycbc.waveform.get_td_waveform wrapper.

    Parameters
    ----------
    f_ref : Reference frequency (?For setting phi_ref? Not sure.) Defaults to f_min.
    phi_ref : Reference phase (?at f_ref?).

    Returns
    -------
    h : Waveform
    """
    if f_ref == None:
        f_ref = p['f_min']

    # Set extra arguments in the lal Dict structure
    lal_pars = lal.CreateDict()
    if phase_order != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNPhaseOrder(
            lal_pars, int(phase_order))
    if amplitude_order != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNAmplitudeOrder(
            lal_pars, int(amplitude_order))
    if spin_order != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNSpinOrder(
            lal_pars, int(spin_order))
    if tidal_order != -1:
        lalsimulation.SimInspiralWaveformParamsInsertPNTidalOrder(
            lal_pars, int(tidal_order))
    if p['lambda1']:
        lalsimulation.SimInspiralWaveformParamsInsertTidalLambda1(
            lal_pars, p['lambda1'])
    if p['lambda2']:
        lalsimulation.SimInspiralWaveformParamsInsertTidalLambda2(
            lal_pars, p['lambda2'])
    # Add spin-induced quadrupole terms. Default is universal relations.
    # dQuadMon1 = quad1 - 1
    # dQuadMon2 = quad2 - 1
    if quad1 == None:
        quad1 = taylorf2.quad_of_lambda_fit(p['lambda1'])
    if quad2 == None:
        quad2 = taylorf2.quad_of_lambda_fit(p['lambda2'])
    lalsimulation.SimInspiralWaveformParamsInsertdQuadMon1(
        lal_pars, quad1 - 1.0)
    lalsimulation.SimInspiralWaveformParamsInsertdQuadMon2(
        lal_pars, quad2 - 1.0)
    print quad1, quad2
    print 'dQuadMon1 =', lalsimulation.SimInspiralWaveformParamsLookupdQuadMon1(
        lal_pars)
    print 'dQuadMon2 =', lalsimulation.SimInspiralWaveformParamsLookupdQuadMon2(
        lal_pars)

    # Set Approximant (C enum structure) corresponding to approximant string
    lal_approx = lalsimulation.GetApproximantFromString(p['approximant'])

    hp, hc = lalsimulation.SimInspiralChooseFDWaveform(
        float(MSUN_SI * p['mass1']), float(MSUN_SI * p['mass2']),
        float(p['spin1x']), float(p['spin1y']), float(p['spin1z']),
        float(p['spin2x']), float(p['spin2y']), float(p['spin2z']),
        float(MPC_SI * p['distance']), float(p['inclination']), float(phi_ref),
        float(long_asc_nodes), float(eccentricity), float(mean_per_ano),
        float(p['delta_f']), float(p['f_min']), float(p['f_max']),
        float(f_ref), lal_pars, lal_approx)

    # Extract data from lalsimulation's structures
    # The first data point in hp.data.data corresponds to f=0 not f=f_min
    fs = hp.deltaF * np.arange(hp.data.length)
    return wave.Waveform.from_hp_hc(fs, hp.data.data, hc.data.data)