Exemple #1
0
def _get_imr_duration(m1, m2, s1z, s2z, f_low, approximant="SEOBNRv4"):
    """Wrapper of lalsimulation template duration approximate formula"""
    m1, m2, s1z, s2z, f_low = float(m1), float(m2), float(s1z), float(s2z),\
                              float(f_low)
    if approximant == "SEOBNRv2":
        chi = lalsimulation.SimIMRPhenomBComputeChi(m1, m2, s1z, s2z)
        time_length = lalsimulation.SimIMRSEOBNRv2ChirpTimeSingleSpin(
                                m1 * lal.MSUN_SI, m2 * lal.MSUN_SI, chi, f_low)
    elif approximant == "IMRPhenomD":
        time_length = lalsimulation.SimIMRPhenomDChirpTime(
                           m1 * lal.MSUN_SI, m2 * lal.MSUN_SI, s1z, s2z, f_low)
    elif approximant == "SEOBNRv4":
        # NB for no clear reason this function has f_low as first argument
        time_length = lalsimulation.SimIMRSEOBNRv4ROMTimeOfFrequency(
                           f_low, m1 * lal.MSUN_SI, m2 * lal.MSUN_SI, s1z, s2z)
    elif approximant == 'SPAtmplt' or approximant == 'TaylorF2':
        chi = lalsimulation.SimInspiralTaylorF2ReducedSpinComputeChi(
            m1, m2, s1z, s2z
        )
        time_length = lalsimulation.SimInspiralTaylorF2ReducedSpinChirpTime(
            f_low, m1 * lal.MSUN_SI, m2 * lal.MSUN_SI, chi, -1
        )
    else:
        raise RuntimeError("I can't calculate a duration for %s" % approximant)
    # FIXME Add an extra factor of 1.1 for 'safety' since the duration
    # functions are approximate
    return time_length * 1.1
    def __init__(self, m1, m2, spin1z, spin2z, bank, flow=None, duration=None):

        AlignedSpinTemplate.__init__(self, m1, m2, spin1z, spin2z, bank,
                                     flow=flow, duration=duration)
        self.chired = lalsim.SimInspiralTaylorF2ReducedSpinComputeChi(m1, m2, spin1z, spin2z)
        self._eta = m1*m2/(m1+m2)**2
        self._theta0, self._theta3, self._theta3s = compute_chirptimes(self._mchirp, self._eta, self.chired, self.flow)
Exemple #3
0
    def __init__(self, m1, m2, spin1z, spin2z, bank, flow=None, duration=None):

        warn_msg = ("DEPRECATION WARNING: It is not a good idea to use this "
                    "approximant. The TaylorF2 approximant is the best thing "
                    "to use if you are constructing a 'brute-force match' "
                    "bank. This allows the use of both spins correctly, and "
                    "the inclusion of all PN terms currently known. "
                    "If using the metric, the implementation in PyCBC, which "
                    "gets terms directly from lalsimulation, and so "
                    "automatically stays up to date, is more accurate.")
        logging.warn(warn_msg)
        AlignedSpinTemplate.__init__(self, m1, m2, spin1z, spin2z, bank,
                                     flow=flow, duration=duration)
        self.chired = lalsim.SimInspiralTaylorF2ReducedSpinComputeChi(
            m1,
            m2,
            spin1z,
            spin2z
        )
        self._eta = m1*m2/(m1+m2)**2
        self._theta0, self._theta3, self._theta3s = compute_chirptimes(
            self._mchirp,
            self._eta,
            self.chired,
            self.flow
        )
Exemple #4
0
    def __init__(self, m1, m2, spin1z, spin2z, bank):

        AlignedSpinTemplate.__init__(self, m1, m2, spin1z, spin2z, bank)
        self.chired = lalsim.SimInspiralTaylorF2ReducedSpinComputeChi(
            m1, m2, spin1z, spin2z)
        self._dur = self._get_dur()
        self._eta = m1 * m2 / (m1 + m2)**2
        self._theta0, self._theta3, self._theta3s = compute_chirptimes(
            self._mchirp, self._eta, self.chired, self.bank.flow)
Exemple #5
0
    def __init__(self, m1, m2, spin1z, spin2z, bank, flow=None, duration=None):

        self.chired = lalsim.SimInspiralTaylorF2ReducedSpinComputeChi(
            m1,
            m2,
            spin1z,
            spin2z
        )
        AlignedSpinTemplate.__init__(self, m1, m2, spin1z, spin2z, bank,
                                     flow=flow, duration=duration)
Exemple #6
0
    def __init__(self, m1, m2, s1x, s1y, s1z, s2x, s2y, s2z, inclination,
                 theta, phi, psi, bank):
        Template.__init__(self, m1, m2, bank)
        self.m1 = float(m1)
        self.m2 = float(m2)
        self.s1x = float(s1x)
        self.s1y = float(s1y)
        self.s1z = float(s1z)
        self.s2x = float(s2x)
        self.s2y = float(s2y)
        self.s2z = float(s2z)
        self.inclination = float(inclination)
        self.theta = float(theta)
        self.phi = float(phi)
        self.psi = float(psi)
        self.bank = bank

        # derived quantities
        self._dur = lalsim.SimInspiralTaylorF2ReducedSpinChirpTime(
            bank.flow, m1 * MSUN_SI, m2 * MSUN_SI,
            lalsim.SimInspiralTaylorF2ReducedSpinComputeChi(
                self.m1 * MSUN_SI, self.m2 * MSUN_SI, self.s1z, self.s2z), 7)
        self._mchirp = compute_mchirp(m1, m2)
Exemple #7
0
 def chi(self):
     return lalsimulation.SimInspiralTaylorF2ReducedSpinComputeChi(
         self.mass1, self.mass2, self.spin1z, self.spin2z)
Exemple #8
0
    def __init__(self, m1, m2, spin1z, spin2z, bank):

        self.chired = lalsim.SimInspiralTaylorF2ReducedSpinComputeChi(
            m1, m2, spin1z, spin2z)
        AlignedSpinTemplate.__init__(self, m1, m2, spin1z, spin2z, bank)
def evolve_spins_dt(v0, m1, m2, chi1x, chi1y, chi1z, chi2x, chi2y, chi2z, Lnx,
                    Lny, Lnz, v_final, dt):
    """ evolve the spins and orb ang momentum according to the PN precession eqns."""

    # Set maximum dv/dt for stopping condition

    dvdt_max = 1.e-4

    # Set maximum deviation from v_final allowed (unless dv/dt is greater than dvdt_max or negative, in which case just print a warning)

    delta_vf_max = 1.e-2

    # Set largest deviation from normalization of orbital angular momentum allowed

    delta_Lnorm_max = 1.e-8

    # Give indices for various quantities in the solution vector

    V_POS = 0  # Location of v (and thus dv/dt)

    LNX_POS = 7  # Location of the x component of Ln
    LNY_POS = 8  # Location of the y component of Ln
    LNZ_POS = 9  # Location of the z component of Ln

    # some sanity checks
    if m1 < 0:
        raise ValueError("ERROR: mass1 is negative")
    if m2 < 0:
        raise ValueError("ERROR: mass2 is negative")
    if (chi1x**2 + chi1y**2 + chi1z**2) > 1.:
        raise ValueError("ERROR: magnitude of spin1 is greater than 1")
    if (chi2x**2 + chi2y**2 + chi2z**2) > 1.:
        raise ValueError("ERROR: magnitude of spin2 is greater than 1")
    if dt < 0:
        raise ValueError("ERROR: time step is negative")

    m1_sqr = m1 * m1
    m2_sqr = m2 * m2

    # pack the inputs
    y_vec0 = [
        v0, chi1x * m1_sqr, chi1y * m1_sqr, chi1z * m1_sqr, chi2x * m2_sqr,
        chi2y * m2_sqr, chi2z * m2_sqr, Lnx, Lny, Lnz
    ]
    t0 = 0.

    # Defining chi_eff and Newtonian chirp time. T_MAX is set to twice of chirp time.
    chi_eff = lalsim.SimInspiralTaylorF2ReducedSpinComputeChi(
        m1, m2, chi1z, chi2z)
    T_MAX = 2. * lalsim.SimInspiralTaylorF2ReducedSpinChirpTime(
        v0**3. / (PI * (m1 + m2) * MTSUN_SI), m1 * MSUN_SI, m2 * MSUN_SI,
        chi_eff, 0) / MTSUN_SI
    R_TOL = 1e-6
    A_TOL = 1e-6

    #print("T_MAX = %f"%(T_MAX))

    # initialize the ODE solver
    backend = "dopri5"
    solver = ode(precession_eqns)
    solver.set_integrator(backend, atol=R_TOL, rtol=R_TOL)  # nsteps=1
    solver.set_initial_value(y_vec0, t0)
    solver.set_f_params(m1, m2)

    y_result = []
    t_output = []
    y_result.append(y_vec0)
    t_output.append(t0)

    # Set diagnostic quantities to some initial values that won't trigger any stopping conditions

    v_current = 0.
    dvdt_current = 1.e-5
    Lnorm_current = 1.

    # evolve the eqns
    while solver.successful(
    ) and solver.t < 2. * T_MAX and v_current <= v_final and dvdt_current > 0. and dvdt_current < dvdt_max and abs(
            Lnorm_current - 1.) < delta_Lnorm_max:

        solver.integrate(solver.t + dt, step=1)
        y_result.append(solver.y)
        t_output.append(solver.t)

        #print '... t = ', solver.t, ' y = ', solver.y

        v_current = solver.y[V_POS]
        dvdt_current = precession_eqns(solver.t, solver.y, m1, m2)[V_POS]
        Lnorm_current = np.sqrt((solver.y[LNX_POS])**2 +
                                (solver.y[LNY_POS])**2 +
                                (solver.y[LNZ_POS])**2)

    Y = np.array(y_result)
    t = np.array(t_output)

    # Check if the integration stopped more than delta_vf_max away from v_final. If so, check if this occurred because dv/dt became larger than dvdt_max or negative. In this case, print a warning and remove the offending data, else raise an error

    v_last = Y.T[V_POS][-1]

    if abs(v_last - v_final) > delta_vf_max:
        if dvdt_current <= 0 or dvdt_current > dvdt_max:
            Y = np.delete(Y, -1, axis=0)
            print(
                "Warning: Integration stopped at v_max = {0}, more than {1} different from v_final = {2}, because dv/dt became negative or exceeded {3}, with a value of {4}. The final value used is {5}."
                .format(v_last, delta_vf_max, v_final, dvdt_max, dvdt_current,
                        precession_eqns(t, Y[-1], m1, m2)[V_POS]))
        else:
            raise ValueError(
                "v_max = {0} is more than {1} different from v_final = {2} and dv/dt is positive and less than {3}"
                .format(v_v[-1], delta_vf, v_final, dvdt_max))

    if abs(Lnorm_current - 1.) >= delta_Lnorm_max:
        raise ValueError(
            "norm of Ln is more than {0:e} different from 1, with distance {1:e}"
            .format(delta_Lnorm_max, abs(Lnorm_current - 1.)))

    v_v, S1x_v, S1y_v, S1z_v, S2x_v, S2y_v, S2z_v, Lx_v, Ly_v, Lz_v = Y.T

    return v_v, S1x_v / m1_sqr, S1y_v / m1_sqr, S1z_v / m1_sqr, S2x_v / m2_sqr, S2y_v / m2_sqr, S2z_v / m2_sqr, Lx_v, Ly_v, Lz_v
Exemple #10
0
def evolve_spins_dt(v0, m1, m2, chi1x, chi1y, chi1z, chi2x, chi2y, chi2z, Lnx, Lny, Lnz, v_final, dt):
	""" evolve the spins and orb ang momentum according to the PN precession eqns."""

        # some sanity checks
        if m1<0:
            raise ValueError("ERROR: mass1 is negative")
        if m2<0:
            raise ValueError("ERROR: mass2 is negative")
        if (chi1x**2+chi1y**2+chi1z**2)>1.:
            raise ValueError("ERROR: magnitude of spin1 is greater than 1")
        if (chi2x**2+chi2y**2+chi2z**2)>1.:
            raise ValueError("ERROR: magnitude of spin2 is greater than 1")
        if dt<0:
            raise ValueError("ERROR: time step is negative")

	m1_sqr = m1*m1
	m2_sqr = m2*m2

	# pack the inputs
	y_vec0 = [v0, chi1x*m1_sqr, chi1y*m1_sqr, chi1z*m1_sqr, chi2x*m2_sqr, chi2y*m2_sqr, chi2z*m2_sqr, Lnx, Lny, Lnz]
	t0 = 0.

        # Defining chi_eff and Newtonian chirp time. T_MAX is set to twice of chirp time.
        chi_eff = lalsim.SimInspiralTaylorF2ReducedSpinComputeChi(m1, m2, chi1z, chi2z)
	T_MAX = 2.* lalsim.SimInspiralTaylorF2ReducedSpinChirpTime(v0**3./(PI*(m1+m2)*MTSUN_SI), m1*MSUN_SI, m2*MSUN_SI, chi_eff, 0)/MTSUN_SI
	R_TOL = 1e-6
	A_TOL = 1e-6

        #print("T_MAX = %f"%(T_MAX))

	# initialize the ODE solver
	backend = "dopri5"
	solver = ode(precession_eqns)
	solver.set_integrator(backend, atol=R_TOL, rtol=R_TOL)  # nsteps=1
	solver.set_initial_value(y_vec0, t0)
	solver.set_f_params(m1, m2)

	y_result = []
	t_output = []
	y_result.append(y_vec0)
	t_output.append(t0)

	# evolve the eqns
	while solver.successful() and solver.t < 2.*T_MAX and solver.y[0] <= v_final and abs(np.sqrt((solver.y[7])**2+(solver.y[8])**2+(solver.y[9])**2)-1.)<1e-8:

		solver.integrate(solver.t + dt, step=1)
		y_result.append(solver.y)
		t_output.append(solver.t)

		#print '... t = ', solver.t, ' y = ', solver.y

	Y = np.array(y_result)
	t = np.array(t_output)
	v_v, S1x_v, S1y_v, S1z_v, S2x_v, S2y_v, S2z_v, Lx_v, Ly_v, Lz_v  = Y.T

        if abs(v_v[-1]-v_final)>1e-2:
            raise ValueError("v_max = {0} is more than 0.01 different from v_final = {1}".format(v_v[-1], v_final))

        if abs(np.sqrt((solver.y[7])**2+(solver.y[8])**2+(solver.y[9])**2)-1.)>=1e-8:
            raise ValueError("norm of Ln is more than 10^{-8} different from 1, with distance {0}".format(abs(np.sqrt((solver.y[7])**2+(solver.y[8])**2+(solver.y[9])**2)-1.)))

	return v_v, S1x_v/m1_sqr, S1y_v/m1_sqr, S1z_v/m1_sqr, S2x_v/m2_sqr, S2y_v/m2_sqr, S2z_v/m2_sqr, Lx_v, Ly_v, Lz_v