Exemple #1
0
def get_motion_vector(ra, dec, pmra, pmdec, parallax):
    # Return the space motion vector of a star
    # Requirements:
    #   - astropy coordinate object
    #   - proper motion in ra and dec (mas per year)
    #   - parallax (mas)
    #   - radial velocity (km/s)
    # Returns astropy cartesian representation of space motion vector
    # see eqns.
    #   - 11.2
    #   - 12.36
    # in 'Spherical Astronomy' by R.M. Green

    ra = ra * deg2rad
    dec = dec * deg2rad

    vt_ra = pmra / parallax
    vt_dec = pmdec / parallax

    Vtan = numpy.array([
        -vt_ra * np.sin(ra) - vt_dec * np.cos(ra) * np.sin(dec),
        vt_ra * np.cos(ra) - vt_dec * np.sin(ra) * np.sin(dec),
        vt_dec * np.cos(dec)
    ])

    return Vtan
Exemple #2
0
def SphToCartU(trd, plg, k):
    '''
	SphToCartU converts from spherical to cartesian coordinates

	SphToCartU(trd,plg,k) returns the north (cn),
	east (ce), and down (cd) direction cosines of a line.
	Notice that these direction cosines have uncertainties

	k is an integer to tell whether the trend and plunge
	of a line (k = 0) or strike and dip of a plane in right
	hand rule (k = 1) are being sent in the trdu and plgu slots.
	In this last case, the direction cosines of the pole to
	the plane are returned
 
	NOTE: trdu and plgu are in radians and they have
	uncertainties in radians
	
	SphToCartU uses the uncertainties package from
	Eric O. Lebigot
	
	Based on Python function SphToCart
	'''
    # If line
    if k == 0:
        cn = umath.cos(trd) * umath.cos(plg)
        ce = umath.sin(trd) * umath.cos(plg)
        cd = umath.sin(plg)
    # Else pole to plane
    elif k == 1:
        cn = umath.sin(trd) * umath.sin(plg)
        ce = -umath.cos(trd) * umath.sin(plg)
        cd = umath.cos(plg)

    return cn, ce, cd
Exemple #3
0
def calculate_bucket_area_uncertain(radius, wedge_inner, wedge_outer,
                                    wedge_length):
    """Calculate bucket area
    
    Area circle + Area wedge
    """
    from uncertainties.umath import sin
    from pandas import Series
    circumference = 2 * np.pi * radius
    wedge_angle = 2 * np.pi * wedge_inner / circumference
    wedge_area_outside = (wedge_outer * wedge_length +
                          abs(wedge_inner - wedge_outer) * wedge_length)
    wedge_triangle_p = (radius * 2 + wedge_inner) / 2
    wedge_area_inside = (wedge_triangle_p * (wedge_triangle_p - radius)**2 *
                         (wedge_triangle_p - wedge_inner))**0.5
    bucket_area_inside = (
        np.pi * radius**2 - 0.5 * radius**2 *
        (wedge_angle -
         (sin(wedge_angle) if not isinstance(wedge_angle, Series) else
          wedge_angle.apply(lambda x: sin(x)))) +
        (wedge_triangle_p * (wedge_triangle_p - radius)**2 *
         (wedge_triangle_p - wedge_inner))**0.5)
    bucket_area = (bucket_area_inside + wedge_area_inside +
                   wedge_area_outside) / 10_000  # m^2
    return bucket_area
Exemple #4
0
def angular_to_cartesian(ra,dec):
	"""Calculates unit cartesian vector of angular coordinates Right 
	acession and declination [degrees]

	"""

	ra = ra * deg2rad
	dec = dec * deg2rad

	return numpy.array([np.cos(ra) * np.cos(dec), np.sin(ra) * np.cos(dec),
		np.sin(dec)])
Exemple #5
0
def measurement_to_xyz(measurement):
    theta_step, phi_step, dist = measurement
    dist = uncertainties.ufloat(dist, LIDAR_UNCERT)
    theta_step = uncertainties.ufloat(theta_step, 0.05)
    phi_step = uncertainties.ufloat(phi_step, 0.05)
    return np.array([
        dist * umath.cos(theta_step * 360 / STEPS_PER_ROTATION * np.pi / 180) *
        umath.cos(phi_step * 360 / STEPS_PER_ROTATION * np.pi / 180),
        dist * umath.sin(theta_step * 360 / STEPS_PER_ROTATION * np.pi / 180) *
        umath.cos(phi_step * 360 / STEPS_PER_ROTATION * np.pi / 180),
        dist * umath.sin(phi_step * 360 / STEPS_PER_ROTATION * np.pi / 180),
    ])
Exemple #6
0
def rutherford(theta, T, Zi, Zt, which="inc"):
    """
    Rutherford Scattering in the center-of-mass system

    Arguments
    ---------
    theta : scattering angle in the center-of-mass system
    T     : kinetic energy of incident particle in the center-of-mass system
    Zi    : atomic number of incident particle; charge in units of e
    Zt    : atomic number of target particle; charge in units of e
    which : if which="inc", calc dσ/dΩ(θ) of incident particle.
            if which="tar", calc dσ/dΩ(θ) of target particle.
            if which="sum", calc dσ/dΩ(θ) of incident particle + dσ/dΩ(θ) of target particle.

    Return
    ------
    dσ/dΩ(θ) in the center-of-mass system [mb/str]
    """
    # dσ/dΩ[mb/str]
    # 10.0 : fm^2 --> mb
    if which == "inc":
        # incident particle
        if isinstance(theta, uncertainties.core.AffineScalarFunc):
            return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * umath.pow(umath.sin(theta / 2.0), -4.0)
        elif isinstance(theta, np.ndarray) and isinstance(theta[0], uncertainties.core.AffineScalarFunc):
            return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * unp.pow(unp.sin(theta / 2.0), -4.0)
        else:
            return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * np.power(np.sin(theta / 2.0), -4.0)
    elif which == "tar":
        # target particle
        if isinstance(theta, uncertainties.core.AffineScalarFunc):
            return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * umath.pow(umath.cos(theta / 2.0), -4.0)
        elif isinstance(theta, np.ndarray) and isinstance(theta[0], uncertainties.core.AffineScalarFunc):
            return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * unp.pow(unp.cos(theta / 2.0), -4.0)
        else:
            return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 * np.power(np.cos(theta / 2.0), -4.0)
    elif which == "sum":
        # incident particle + target particle
        if isinstance(theta, uncertainties.core.AffineScalarFunc):
            return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 \
                * (umath.pow(umath.sin(theta / 2.0), -4.0) + umath.pow(umath.cos(theta / 2.0), -4.0))
        elif isinstance(theta, np.ndarray) and isinstance(theta[0], uncertainties.core.AffineScalarFunc):
            return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 \
                * (unp.pow(unp.sin(theta / 2.0), -4.0) + unp.power(unp.cos(theta / 2.0), -4.0))
        else:
            return 10.0 * (Zi * Zt * E2 / (4.0 * T))**2.0 \
                * (np.power(np.sin(theta / 2.0), -4.0) + np.power(np.cos(theta / 2.0), -4.0))
    else:
        raise ValueError(
            f"Unrecognized which option:{which}. which must be inc/tar/sum.")
Exemple #7
0
def test_numerical_example():
    "Test specific numerical examples"

    x = ufloat(3.14, 0.01)
    result = umath.sin(x)
    # In order to prevent big errors such as a wrong, constant value
    # for all analytical and numerical derivatives, which would make
    # test_fixed_derivatives_math_funcs() succeed despite incorrect
    # calculations:
    assert ("%.6f +/- %.6f" %
            (result.nominal_value, result.std_dev) == "0.001593 +/- 0.010000")

    # Regular calculations should still work:
    assert ("%.11f" % umath.sin(3) == "0.14112000806")
def test_numerical_example():
    "Test specific numerical examples"

    x = uncertainties.ufloat((3.14, 0.01))
    result = umath.sin(x)
    # In order to prevent big errors such as a wrong, constant value
    # for all analytical and numerical derivatives, which would make
    # test_fixed_derivatives_math_funcs() succeed despite incorrect
    # calculations:
    assert ("%.6f +/- %.6f" % (result.nominal_value, result.std_dev())
            == "0.001593 +/- 0.010000")

    # Regular calculations should still work:
    assert("%.11f" % umath.sin(3) == "0.14112000806")
def trail(rF, lam, fo):
    '''Calculate the trail and mechanical trail.

    Parameters
    ----------
    rF : float
        The front wheel radius
    lam : float
        The steer axis tilt (pi/2 - headtube angle). The angle between the
        headtube and a vertical line.
    fo : float
        The fork offset

    Returns
    -------
    c: float
        Trail
    cm: float
        Mechanical Trail

    '''

    # trail
    c = (rF * umath.sin(lam) - fo) / umath.cos(lam)
    # mechanical trail
    cm = c * umath.cos(lam)
    return c, cm
def inclination(b, a, e=0, w=90):
    """
    Function to convert impact parameter b to inclination in degrees.
    
        
    Parameters:
    ----------
    b: Impact parameter of the transit.
    
    a: Scaled semi-major axis i.e. a/R*.

    e: float;
        eccentricity of the orbit.
    
    w: float;
        longitude of periastron in degrees
    
    Returns
    --------
    
    inc: The inclination of the planet orbit in degrees.
    
    """
    ecc_factor = (1 - e**2) / (1 + e * sin(radians(w)))
    inc = degrees(acos(b / (a * ecc_factor)))
    return inc
def updateMeasurement(z, R):
    tm = np.array([[sin(z[4]) * z[0], cos(z[4]) * z[0], z[2], z[3], z[4]]]).T
    theta_uncertain = ufloat(z[4], 0.5)
    v_uncertain = ufloat(z[0], 0.5)
    R[2, 0] = (umath.sin(theta_uncertain) * v_uncertain).std_dev
    R[3, 0] = (umath.cos(theta_uncertain) * v_uncertain).std_dev
    return [tm, R]
def trail(rF, lam, fo):
    '''Calculate the trail and mechanical trail.

    Parameters
    ----------
    rF : float
        The front wheel radius
    lam : float
        The steer axis tilt (pi/2 - headtube angle). The angle between the
        headtube and a vertical line.
    fo : float
        The fork offset

    Returns
    -------
    c: float
        Trail
    cm: float
        Mechanical Trail

    '''

    # trail
    c = (rF * umath.sin(lam) - fo) / umath.cos(lam)
    # mechanical trail
    cm = c * umath.cos(lam)
    return c, cm
Exemple #13
0
def theta(theta_cm, n):
    """
    function to convert θ in the center-of-mass system to θ in the lab system

    Arguments
    ---------
    theta_cm : scattering angle in the center-of-mass system [rad]
    n        : A_t / A_i; A_t, A_i means mass number of target particle or incident particle

    Return
    ------
    theta_lab : scattering angle in the lab system [rad]

    Notice
    ------
    This function does not consider relativity
    """
    if isinstance(theta_cm, uncertainties.core.AffineScalarFunc):
        return umath.arctan(
            umath.sin(theta_cm) / (1.0 / n + umath.cos(theta_cm)))
    elif isinstance(theta_cm, np.ndarray) and isinstance(
            theta_cm[0], uncertainties.core.AffineScalarFunc):
        return unp.arctan(unp.sin(theta_cm) / (1.0 / n + unp.cos(theta_cm)))
    else:
        return np.arctan(np.sin(theta_cm) / (1.0 / n + np.cos(theta_cm)))
Exemple #14
0
    def dS(self, a):
        """
        Arguments
        ---------
        a : angle of rotation [rad]

        Return
        ------
        ΔS : detection area [mm^2]
        """
        Rd = self.R + self.d
        r = self.r
        AT = self.AT
        D0 = self.D(0.0)
        A0 = umath.acos((Rd**2.0 + D0**2.0 - r**2.0) / (2.0 * Rd * D0))
        d = self.d
        w = self.w
        h = self.h
        if isinstance(a, (int, float, np.number, uncertainties.core.AffineScalarFunc)):
            phi = umath.fabs(a - A0 - self.theta(a))
            # ΔS
            return w * h * umath.cos(phi) - d * h * umath.sin(phi)
        elif isinstance(a, np.ndarray):
            phi = unp.fabs(a - A0 - self.theta(a))
            return w * h * unp.cos(phi) - d * h * unp.sin(phi)
        else:
            raise ValueError(
                f"This function not supported for the input types. argument 'a' must be number or array")
def test_math_module():
    "Operations with the math module"

    x = uncertainties.ufloat((-1.5, 0.1))
    
    # The exponent must not be differentiated, when calculating the
    # following (the partial derivative with respect to the exponent
    # is not defined):
    assert (x**2).nominal_value == 2.25

    # Regular operations are chosen to be unchanged:
    assert isinstance(umath.sin(3), float)

    # Python >=2.6 functions:

    if sys.version_info[:2] >= (2, 6):
    
        # factorial() must not be "damaged" by the umath module, so as 
        # to help make it a drop-in replacement for math (even though 
        # factorial() does not work on numbers with uncertainties 
        # because it is restricted to integers, as for 
        # math.factorial()):
        assert umath.factorial(4) == 24

        # Boolean functions:
        assert not umath.isinf(x)

        # Comparison, possibly between an AffineScalarFunc object and a
        # boolean, which makes things more difficult for this code:
        assert umath.isinf(x) == False

        # fsum is special because it does not take a fixed number of
        # variables:
        assert umath.fsum([x, x]).nominal_value == -3
Exemple #16
0
def distance_to_steer_axis(w, c, lam, point):
    """Returns the minimal distance from the steer axis to the given point when
    the bicycle is in the nominal configuration.

    Parameters
    ----------
    w : float or ufloat
        Wheelbase.
    c : float or ufloat
        Trail.
    lam : float or ufloat
        Steer axis tilt in radians.
    point : narray, shape(3,)
        A point that lies in the symmetry plane of the bicycle.

    Returns
    -------
    d : float or ufloat
        The minimal distance from the given point to the steer axis.

    """
    pointOnAxis1 = np.array([w + c, 0., 0.])
    pointOnAxis2 = pointOnAxis1 +\
                   np.array([-umath.sin(lam),
                             0.,
                             -umath.cos(lam)])
    pointsOnLine = np.array([pointOnAxis1, pointOnAxis2]).T

    # this is the distance from the assembly com to the steer axis
    return point_to_line_distance(point, pointsOnLine)
Exemple #17
0
def CalcR2eff(kR1p, pB, pC, dwB, dwC, kexAB, kexAC, kexBC, R1, w1, wrf, lf, AlignMag = "auto", Error = False):

    # Convert w1, wrf to rad/sec from Hz
    w1 = float(w1) * 2. * pi
    wrf = float(wrf) * 2. * pi

    # Calc other simple parameters
    pA = 1. - (pB + pC)
    lf = float(lf)
    #Convert dw from ppm to rad/s
    dwB = dwB * lf * 2. * pi # dw(ppm) * base-freq (eg 151 MHz, but just 151) * 2PI, gives rad/s
    dwC = dwC * lf * 2. * pi

    ################################
    #####  R2eff Calculations  #####
    ################################

    # Calculate pertinent frequency offsets/etc for alignment and projection
    lOmegaA, lOmegaB, lOmegaC, uOmega1, uOmega2, uOmega3, uOmegaAvg,\
    delta1, delta2, delta3, deltaAvg, theta1, theta2, theta3, thetaAvg = \
                            AlignMagVec(w1, wrf, pA, pB, pC, dwB, dwC, kexAB, kexAC, kexBC, AlignMag)

    if Error == False:
        r2e = (kR1p/sin(thetaAvg)**2.) - (R1/(tan(thetaAvg)**2.))
        return r2e
    else:
        r2e = (kR1p/umath.sin(thetaAvg)**2.) - (R1/(umath.tan(thetaAvg)**2.))
        return r2e
def distance_to_steer_axis(w, c, lam, point):
    """Returns the minimal distance from the steer axis to the given point when
    the bicycle is in the nominal configuration.

    Parameters
    ----------
    w : float or ufloat
        Wheelbase.
    c : float or ufloat
        Trail.
    lam : float or ufloat
        Steer axis tilt in radians.
    point : narray, shape(3,)
        A point that lies in the symmetry plane of the bicycle.

    Returns
    -------
    d : float or ufloat
        The minimal distance from the given point to the steer axis.

    """
    pointOnAxis1 = np.array([w + c,
                             0.,
                             0.])
    pointOnAxis2 = pointOnAxis1 +\
                   np.array([-umath.sin(lam),
                             0.,
                             -umath.cos(lam)])
    pointsOnLine = np.array([pointOnAxis1, pointOnAxis2]).T

    # this is the distance from the assembly com to the steer axis
    return point_to_line_distance(point, pointsOnLine)
Exemple #19
0
def dOmega(theta_lab, n):
    """
    function to find dΩlab/dΩcm

    Arguments
    ---------
    theta_lab : scattering angle in the lab system [rad]
    n         : A_t / A_i; A_t, A_i means mass number of target particle or incident particle

    Return
    ------
      dΩlab/dΩcm : factor to convert differential cross-section in the lab system to differential cross-section in the center-of-mass system

    Notice
    ------
    This function do not consider relativity
    """
    if isinstance(theta_lab, uncertainties.core.AffineScalarFunc):
        return umath.pow(
            2.0 * umath.cos(theta_lab) / n +
            (1.0 + umath.cos(2.0 * theta_lab) / (n**2.0)) /
            umath.sqrt(1.0 - umath.pow(umath.sin(theta_lab) / n, 2.0)), -1.0)
    elif isinstance(theta_lab, np.ndarray) and isinstance(
            theta_lab[0], uncertainties.core.AffineScalarFunc):
        return unp.pow(
            2.0 * unp.cos(theta_lab) / n +
            (1.0 + unp.cos(2.0 * theta_lab) /
             (n**2.0)) / unp.sqrt(1.0 - unp.pow(unp.sin(theta_lab) / n, 2.0)),
            -1.0)
    else:
        return np.power(
            2.0 * np.cos(theta_lab) / n +
            (1.0 + np.cos(2.0 * theta_lab) /
             (n**2.0)) / np.sqrt(1.0 - np.power(np.sin(theta_lab) / n, 2.0)),
            -1.0)
Exemple #20
0
def measurement_to_xyz(measurement):
    try:
        theta_step, phi_step, dist = measurement
    except Exception as e:
        print("unpacking point failed")
        return np.array([0, 0, 0])
    dist = uncertainties.ufloat(dist, LIDAR_UNCERT)
    theta_step = uncertainties.ufloat(theta_step, 0.05)
    phi_step = uncertainties.ufloat(-phi_step, 0.05)
    return np.array([
        dist * umath.cos(theta_step * 360 / STEPS_PER_ROTATION * np.pi / 180) *
        umath.cos(phi_step * 360 / STEPS_PER_ROTATION * np.pi / 180),
        dist * umath.sin(theta_step * 360 / STEPS_PER_ROTATION * np.pi / 180) *
        umath.cos(phi_step * 360 / STEPS_PER_ROTATION * np.pi / 180),
        dist * umath.sin(phi_step * 360 / STEPS_PER_ROTATION * np.pi / 180),
    ])
Exemple #21
0
def test_math_module():
    "Operations with the math module"

    x = uncertainties.ufloat((-1.5, 0.1))

    # The exponent must not be differentiated, when calculating the
    # following (the partial derivative with respect to the exponent
    # is not defined):
    assert (x**2).nominal_value == 2.25

    # Regular operations are chosen to be unchanged:
    assert isinstance(umath.sin(3), float)

    # Python >=2.6 functions:

    if sys.version_info[:2] >= (2, 6):

        # factorial() must not be "damaged" by the umath module, so as
        # to help make it a drop-in replacement for math (even though
        # factorial() does not work on numbers with uncertainties
        # because it is restricted to integers, as for
        # math.factorial()):
        assert umath.factorial(4) == 24

        # Boolean functions:
        assert not umath.isinf(x)

        # Comparison, possibly between an AffineScalarFunc object and a
        # boolean, which makes things more difficult for this code:
        assert umath.isinf(x) == False

        # fsum is special because it does not take a fixed number of
        # variables:
        assert umath.fsum([x, x]).nominal_value == -3
Exemple #22
0
def transit_prob(Rp, aR, e=0, w=90):
    """
	Function to calculate period of rotation of a planet
	
	Parameters
	-----------
    Rp: float;
        radius of the planet in unit f the stellar radius
    
    aR: float;
        Scaled semi-major axis i.e. a/R*.

    e: float;
        eccentricity of the orbit.
    
    w: float;
        longitude of periastron in degrees
    
		
    """
	#eqn 5 - Kane & von Braun 2008, https://core.ac.uk/reader/216127860
    prob = (1 + Rp)/aR * (1 + e*sin(radians(w))/(1-e**2)  )

	
    return prob
Exemple #23
0
def output_params(timedays, NormFlux, fit, success, period, ecc, arg_periapsis):
    Flux, Ing, Egr = transiterout(np.arange(0, np.size(NormFlux)), fit[0], fit[1], fit[2], fit[3], fitting=True)
    print Ing

    # Get values and uncertainties from the fit
    Rp = ufloat((fit[0], np.sqrt(success[0][0])))
    b1 = ufloat((fit[1], np.sqrt(success[1][1])))
    vel = ufloat((fit[2], np.sqrt(success[2][2])))
    midtrantime = ufloat((fit[3], np.sqrt(success[3][3])))
    # gam1=ufloat((fit[4],np.sqrt(success[4][4])))
    # gam2=ufloat((fit[5],np.sqrt(success[5][5])))

    P = period
    ecc_corr = np.sqrt(1 - ecc ** 2) / (1 + ecc * umath.sin(arg_periapsis * np.pi / 180.0))
    Ttot = (Egr[np.size(Egr) - 1] - Ing[0]) * ecc_corr
    Tfull = (Egr[0] - Ing[np.size(Ing) - 1]) * ecc_corr
    # delta=ufloat((1-Flux[fit[3]],1-Flux[fit[3]]+sqrt(success[3][3])))
    delta = Rp ** 2
    dt = timedays[2] - timedays[1]

    aRstar = (
        2 * delta ** 0.25 * P / (np.pi * dt * umath.sqrt(Ttot ** 2 - Tfull ** 2))
    )  # *umath.sqrt(1-ecc**2)/(1+ecc*sin(arg_periapsis*pi/180.))
    # bmodel=umath.sqrt((1-(Tfull/Ttot)**2)/((1-umath.sqrt(delta))**2-(Tfull/Ttot)**2 * (1+umath.sqrt(delta))**2)) #Not too sure why this doesn't work
    inc = (180 / np.pi) * umath.acos(b1 / aRstar)
    # print bmodel

    poutnames = ("Rp", "b1", "vel", "midtrantime", "gam1", "gam2")
    for iz in range(0, np.size(fit)):
        print poutnames[iz], fit[iz], np.sqrt(success[iz][iz])

    print "--------------------------------"

    # Useful Conversions
    # R_Jup/R_Sun = 0.10279
    # R_Sun = 0.00464913034 AU
    aRstarFIT = vel * P / (dt * 2 * np.pi)
    incFIT = (180 / np.pi) * umath.acos(b1 / aRstarFIT)
    # midtrantime_convert=midtrantime*dt*24*3600+time_days[0]
    # midtrantime_MJD=timedays[midtrantime]+54964.00111764
    timebetween = timedays[int(midtrantime.nominal_value) + 1] - timedays[int(midtrantime.nominal_value)]
    print timebetween * dt

    # print "Midtrantime",midtrantime_convert.std_dev()#midtrantime_MJD
    print "aRstarFIT", aRstarFIT
    print "inclination", incFIT
    print "frac. rad.", Rp
    print "aRstar_mod", aRstar
    aRs = (aRstarFIT + aRstar) / 2
    print "--------------------------------"
    print "Planetary Radius/Star Radius: ", Rp
    print "Inclination: ", incFIT
    print "Semi - Major Axis / Stellar Radius: ", aRs
    print "Mid-Transit Time [MJD]",
    pyplot.plot(time, NormFlux, linestyle="None", marker=".")
    pyplot.plot(time, transiter(np.arange(np.size(NormFlux)), fit[0], fit[1], fit[2], fit[3]))
    pyplot.show()

    return Flux, Rp, aRstarFIT, incFIT, aRstar, midtrantime
Exemple #24
0
def rotate_inertia_tensor(I, angle):
    '''Returns inertia tensor rotated through angle. Only for 2D'''
    ca = umath.cos(angle)
    sa = umath.sin(angle)
    C    =  np.array([[ca, 0., -sa],
                      [0., 1., 0.],
                      [sa, 0., ca]])
    Irot =  np.dot(C, np.dot(I, C.T))
    return Irot
Exemple #25
0
def get_angular_sep1(ra1, dec1, ra2, dec2):
    """Calculates the angular separation of two points on the
        sphere using great circles distance formula.

        returns angular separation in [mas]
        """

    ra1 = ra1 * deg2rad
    ra2 = ra2 * deg2rad

    dec1 = dec1 * deg2rad
    dec2 = dec2 * deg2rad

    dist = np.acos(
        np.sin(dec1) * np.sin(dec2) +
        (np.cos(dec1) * np.cos(dec2) * np.cos(ra1 - ra2)))

    return (dist / deg2rad) * 3600.0 * 1000.0
def test_compound_expression():
    """
    Test equality between different formulas.
    """
    
    x = uncertainties.ufloat((3, 0.1))
    
    # Prone to numerical errors (but not much more than floats):
    assert umath.tan(x) == umath.sin(x)/umath.cos(x)
Exemple #27
0
def get_angular_sep(ra1, dec1, ra2, dec2):

    ra1 = ra1 * deg2rad
    ra2 = ra2 * deg2rad

    dec1 = dec1 * deg2rad
    dec2 = dec2 * deg2rad

    top = np.sqrt((np.cos(dec2) * np.sin(ra2 - ra1))**(2) +
                  (np.cos(dec1) * np.sin(dec2) -
                   np.sin(dec1) * np.cos(dec2) * np.cos(ra2 - ra1))**(2))

    bottom = (np.sin(dec1) * np.sin(dec2)) + (np.cos(dec1) * np.cos(dec2) *
                                              np.cos(ra2 - ra1))

    dist = np.atan2(top, bottom)

    return (dist / deg2rad) * 3600.0 * 1000.0
Exemple #28
0
def test_compound_expression():
    """
    Test equality between different formulas.
    """

    x = ufloat(3, 0.1)

    # Prone to numerical errors (but not much more than floats):
    assert umath.tan(x) == umath.sin(x) / umath.cos(x)
Exemple #29
0
def test_math_module():
    "Operations with the math module"

    x = ufloat(-1.5, 0.1)
    
    # The exponent must not be differentiated, when calculating the
    # following (the partial derivative with respect to the exponent
    # is not defined):
    assert (x**2).nominal_value == 2.25

    # Regular operations are chosen to be unchanged:
    assert isinstance(umath.sin(3), float)

    # Python >=2.6 functions:

    if sys.version_info >= (2, 6):
    
        # factorial() must not be "damaged" by the umath module, so as 
        # to help make it a drop-in replacement for math (even though 
        # factorial() does not work on numbers with uncertainties 
        # because it is restricted to integers, as for 
        # math.factorial()):
        assert umath.factorial(4) == 24

        # Boolean functions:
        assert not umath.isinf(x)

        # Comparison, possibly between an AffineScalarFunc object and a
        # boolean, which makes things more difficult for this code:
        assert umath.isinf(x) == False

        # fsum is special because it does not take a fixed number of
        # variables:
        assert umath.fsum([x, x]).nominal_value == -3

    # The same exceptions should be generated when numbers with uncertainties
    # are used:

    ## !! The Nose testing framework seems to catch an exception when
    ## it is aliased: "exc = OverflowError; ... except exc:..."
    ## surprisingly catches OverflowError. So, tests are written in a
    ## version-specific manner (until the Nose issue is resolved).

    if sys.version_info < (2, 6):
            
        try:
            math.log(0)
        except OverflowError, err_math:  # "as", for Python 2.6+
            pass
        else:
            raise Exception('OverflowError exception expected')
        try:
            umath.log(0)
        except OverflowError, err_ufloat:  # "as", for Python 2.6+
            assert err_math.args == err_ufloat.args
Exemple #30
0
def transit_duration(P, Rp, a, b=0, e=0, w=90, inc=None, total=True):
    
    """
    Function to calculate the total (T14) or full (T23) transit duration
    
    Parameters:
    ----------
    
    P: Period of planet orbit in days

    Rp: Radius of the planet in units of stellar radius

    b: Impact parameter of the planet transit [0, 1+Rp]

    a: scaled semi-major axis of the planet in units of solar radius
    
    inc: inclination of the orbit. Optional. If given b is not used. if None, b is used to calculate inc
    
    total: if True calculate the the total transit duration T14, else calculate duration of full transit T23

    Returns
    -------
    Tdur: duration of transit in same unit as P   
    
    """
    #eqn 30 and 31 of Kipping 2010 https://doi.org/10.1111/j.1365-2966.2010.16894.x
        
    factor = (1-e**2)/(1+e*sin(radians(w)))
    if inc == None:
        inc = inclination(b,a,e,w)
    
    if total is False:
        Rp = -Rp
        
    sini = sin(radians(inc))
    cosi = cos(radians(inc))
    
    denom = a*factor*sini
    
    tdur= (P/np.pi) * (factor**2/sqrt(1-e**2)) * (asin ( sqrt((1+Rp)**2 - (a*factor*cosi)**2)/ denom ) )
    
    return  tdur
Exemple #31
0
def GetOtherFacts(s1, s2, s3, a1, a2, a3, d):
    '''Calculate the other relevant measures of the triangle.
    '''
    A = s1*s2*sin(a3)/2
    s = (s1 + s2 + s3)/2
    r = A/s
    R = s1*s2*s3/(4*A)
    d["area"] = A
    d["perimeter"] = 2*s
    d["r_inscribed"] = r
    d["R_circumscribed"] = R
Exemple #32
0
def TrueThicknessU(strike,dip,top,base):
	'''
	TrueThicknessU calculates the thickness (t) of a unit
	given the strike (strike) and dip (dip) of the unit,
	and points at its top (top) and base (base).
	strike and dip, as well as the points have
	uncertainties.

	top and base are 1 x 3 arrays defining the location
	of top and base points in an ENU coordinate system.
	For each one of these arrays, the first, second
	and third entries are the E, N and U coordinates.
	These coordinates have uncertainties

	NOTE: strike and dip should be input in radians and
		they have uncertainties in radians. The
		returned thickness have also uncertainties
	'''
	# make the transformation matrix from ENU coordinates
	# to SDP coordinates. Eq. 5.10
	sinStr = umath.sin(strike)
	cosStr = umath.cos(strike)
	sinDip = umath.sin(dip)
	cosDip = umath.cos(dip)
	a = np.array([[sinStr, cosStr, unc.ufloat(0,0)],
	[cosStr*cosDip, -sinStr*cosDip, -sinDip],
	[-cosStr*sinDip, sinStr*sinDip, -cosDip]])
	
	# transform the top and base points
	# from ENU to SDP coordinates. Eq. 5.4
	topn = np.array([unc.ufloat(0,0), unc.ufloat(0,0), unc.ufloat(0,0)])
	basen = np.array([unc.ufloat(0,0), unc.ufloat(0,0), unc.ufloat(0,0)])
	for i in range(0,3):
		for j in range(0,3):
			topn[i] = a[i,j]*top[j] + topn[i]
			basen[i] = a[i,j]*base[j] + basen[i]
	
	# compute the thickness of the unit. Eq. 5.12
	t = np.abs(basen[2] - topn[2])
	
	return t
def fwheel_to_handlebar_ref(lam, l1, l2):
    '''Returns the distance along the benchmark coordinates from the front
    wheel center to the handlebar reference center.

    Parameters
    ----------
    lam : float
        Steer axis tilt.
    l1, l2 : float
        The distance from the front wheel center to the handlebar refernce
        center perpendicular to and along the steer axis.

    Returns
    -------
    u1, u2 : float

    '''

    u1 = l2 * umath.sin(lam) - l1 * umath.cos(lam)
    u2 = u1 / umath.tan(lam) + l1 / umath.sin(lam)
    return u1, u2
Exemple #34
0
def fwheel_to_handlebar_ref(lam, l1, l2):
    '''Returns the distance along the benchmark coordinates from the front
    wheel center to the handlebar reference center.

    Parameters
    ----------
    lam : float
        Steer axis tilt.
    l1, l2 : float
        The distance from the front wheel center to the handlebar refernce
        center perpendicular to and along the steer axis.

    Returns
    -------
    u1, u2 : float

    '''

    u1 = l2 * umath.sin(lam) - l1 * umath.cos(lam)
    u2 = u1 / umath.tan(lam) + l1 / umath.sin(lam)
    return u1, u2
Exemple #35
0
def get_angular_sep(ra1, dec1, ra2, dec2):
    """
	implements the vincinerty distance formular in the case
	of a sphere.
	"""

    ra1 = ra1 * deg2rad
    ra2 = ra2 * deg2rad

    dec1 = dec1 * deg2rad
    dec2 = dec2 * deg2rad

    top = np.sqrt((np.cos(dec2) * np.sin(ra2 - ra1))**(2) +
                  (np.cos(dec1) * np.sin(dec2) -
                   np.sin(dec1) * np.cos(dec2) * np.cos(ra2 - ra1))**(2))

    bottom = (np.sin(dec1) * np.sin(dec2)) + (np.cos(dec1) * np.cos(dec2) *
                                              np.cos(ra2 - ra1))

    dist = np.atan2(top, bottom)

    return (dist / deg2rad) * 3600.0 * 1000.0
Exemple #36
0
def get_earth_observer_vector_fast(time):
	"""Calculate the position vector of an observer on the earth in
	barcentric cartesian coordinates, approximately and hopefully
	abit faster.
	"""

	n = time-Time('2000-01-01T12:00:00', format='isot', scale='utc')
	# mean longitude of the sun
	L = (280.460 + 0.9856474*n.jd) % 360.0
	# mean anomaly of the sun
	g = (357.528 + 0.9856003*n.jd) % 360.0
	# ecliptic longitude of the sun
	l = L + 1.915*np.sin(np.radians(g)) + 0.020*np.sin(np.radians(2*g))

	# axial tilt of the earth
	# Obliquity of the ecliptic
	epsilon = 23.439 - 0.0000004*n.jd

	return np.array([
		np.cos(np.radians(l)), 
		np.cos(np.radians(epsilon))*np.sin(np.radians(l)), 
		np.sin(np.radians(epsilon))*np.sin(np.radians(l))]) * -1.0
Exemple #37
0
def calculate_benchmark_geometry(mp, par):
    '''Returns the wheelbase, steer axis tilt and the trail.

    Parameters
    ----------
    mp : dictionary
        Dictionary with the measured parameters.
    par : dictionary
        Dictionary with the benchmark parameters.

    Returns
    -------
    par : dictionary
        par with the benchmark geometry added.

    '''
    # calculate the wheel radii
    par['rF'] = mp['dF'] / 2. / pi / mp['nF']
    par['rR'] = mp['dR'] / 2. / pi / mp['nR']

    # calculate the frame/fork fundamental geometry
    if 'w' in mp.keys():  # if there is a wheelbase
        # steer axis tilt in radians
        par['lam'] = pi / 180. * (90. - mp['gamma'])
        # wheelbase
        par['w'] = mp['w']
        # fork offset
        forkOffset = mp['f']
    else:
        h = (mp['h1'], mp['h2'], mp['h3'], mp['h4'], mp['h5'])
        d = (mp['d1'], mp['d2'], mp['d3'], mp['d4'], mp['d'])
        a, b, c = calculate_abc_geometry(h, d)
        par['lam'] = lambda_from_abc(par['rF'], par['rR'], a, b, c)
        par['w'] = (a + b) * umath.cos(par['lam']) + c * umath.sin(par['lam'])
        forkOffset = b

    # trail
    par['c'] = trail(par['rF'], par['lam'], forkOffset)[0]

    # this will simply transfer the lateral force point through to the
    # benchmark parameters, as they are in the benchmark coordinate system
    try:
        par['xcl'] = mp['xcl']
        par['zcl'] = mp['zcl']
    except KeyError:
        pass

    return par
def calculate_benchmark_geometry(mp, par):
    '''Returns the wheelbase, steer axis tilt and the trail.

    Parameters
    ----------
    mp : dictionary
        Dictionary with the measured parameters.
    par : dictionary
        Dictionary with the benchmark parameters.

    Returns
    -------
    par : dictionary
        par with the benchmark geometry added.

    '''
    # calculate the wheel radii
    par['rF'] = mp['dF'] / 2./ pi / mp['nF']
    par['rR'] = mp['dR'] / 2./ pi / mp['nR']

    # calculate the frame/fork fundamental geometry
    if 'w' in mp.keys(): # if there is a wheelbase
        # steer axis tilt in radians
        par['lam'] = pi / 180. * (90. - mp['gamma'])
        # wheelbase
        par['w'] = mp['w']
        # fork offset
        forkOffset = mp['f']
    else:
        h = (mp['h1'], mp['h2'], mp['h3'], mp['h4'], mp['h5'])
        d = (mp['d1'], mp['d2'], mp['d3'], mp['d4'], mp['d'])
        a, b, c = calculate_abc_geometry(h, d)
        par['lam'] = lambda_from_abc(par['rF'], par['rR'], a, b, c)
        par['w'] = (a + b) * umath.cos(par['lam']) + c * umath.sin(par['lam'])
        forkOffset = b

    # trail
    par['c'] = trail(par['rF'], par['lam'], forkOffset)[0]

    # this will simply transfer the lateral force point through to the
    # benchmark parameters, as they are in the benchmark coordinate system
    try:
        par['xcl'] = mp['xcl']
        par['zcl'] = mp['zcl']
    except KeyError:
        pass

    return par
Exemple #39
0
    def get_source_apparent_pos(self, epoch, enlargeFactor=1.0):

        lensPos = self._lens.getRaDec(epoch)
        sourcePos = self._source.getRaDec(epoch)

        shift_mag = self.get_unresolved_centroid_shift_at_epoch(epoch)
        shift_angle = np.atan2(
            (sourcePos[0] - lensPos[0]) * np.cos(numpy.deg2rad(lensPos[1])),
            sourcePos[1] - lensPos[1])

        appSourceRa = sourcePos[0] + (
            (enlargeFactor * shift_mag * np.cos(shift_angle)) / (3600 * 1000))
        appSourceDec = sourcePos[1] + (
            (enlargeFactor * shift_mag * np.sin(shift_angle)) / (36000 * 1000))

        return numpy.array([appSourceRa, appSourceDec])
Exemple #40
0
def test_against_uncertainties_package():
    try:
        from uncertainties import ufloat
        from uncertainties import umath
        from math import sqrt as math_sqrt
    except ImportError:
        return
    X, varX = 0.5, 0.04
    Y, varY = 3, 0.09
    N = 3
    ux = ufloat(X, math_sqrt(varX))
    uy = ufloat(Y, math_sqrt(varY))

    def _compare(result, u):
        Z, varZ = result
        assert abs(Z-u.n)/u.n < 1e-13 and (varZ-u.s**2)/u.s**2 < 1e-13, \
            "expected (%g,%g) got (%g,%g)"%(u.n, u.s**2, Z, varZ)

    def _check_pow(u):
        _compare(pow(X, varX, N), u)

    def _check_unary(op, u):
        _compare(op(X, varX), u)

    def _check_binary(op, u):
        _compare(op(X, varX, Y, varY), u)

    _check_pow(ux**N)
    _check_binary(add, ux + uy)
    _check_binary(sub, ux - uy)
    _check_binary(mul, ux * uy)
    _check_binary(div, ux / uy)
    _check_binary(pow2, ux**uy)

    _check_unary(exp, umath.exp(ux))
    _check_unary(log, umath.log(ux))
    _check_unary(sin, umath.sin(ux))
    _check_unary(cos, umath.cos(ux))
    _check_unary(tan, umath.tan(ux))
    _check_unary(arcsin, umath.asin(ux))
    _check_unary(arccos, umath.acos(ux))
    _check_unary(arctan, umath.atan(ux))
    _check_binary(arctan2, umath.atan2(ux, uy))
Exemple #41
0
def test_against_uncertainties_package():
    try:
        from uncertainties import ufloat
        from uncertainties import umath
        from math import sqrt as math_sqrt
    except ImportError:
        return
    X, varX = 0.5, 0.04
    Y, varY = 3, 0.09
    N = 3
    ux = ufloat(X, math_sqrt(varX))
    uy = ufloat(Y, math_sqrt(varY))

    def _compare(result, u):
        Z, varZ = result
        assert abs(Z-u.n)/u.n < 1e-13 and (varZ-u.s**2)/u.s**2 < 1e-13, \
            "expected (%g,%g) got (%g,%g)"%(u.n,u.s**2,Z,varZ)

    def _check_pow(u):
        _compare(pow(X, varX, N), u)

    def _check_unary(op, u):
        _compare(op(X, varX), u)

    def _check_binary(op, u):
        _compare(op(X, varX, Y, varY), u)

    _check_pow(ux**N)
    _check_binary(add, ux+uy)
    _check_binary(sub, ux-uy)
    _check_binary(mul, ux*uy)
    _check_binary(div, ux/uy)
    _check_binary(pow2, ux**uy)

    _check_unary(exp, umath.exp(ux))
    _check_unary(log, umath.log(ux))
    _check_unary(sin, umath.sin(ux))
    _check_unary(cos, umath.cos(ux))
    _check_unary(tan, umath.tan(ux))
    _check_unary(arcsin, umath.asin(ux))
    _check_unary(arccos, umath.acos(ux))
    _check_unary(arctan, umath.atan(ux))
    _check_binary(arctan2, umath.atan2(ux, uy))
def benchmark_par_to_canonical(p):
    '''Returns the canonical matrices of the Whipple bicycle model linearized
    about the upright constant velocity configuration. It uses the parameter
    definitions from Meijaard et al. 2007.

    Parameters
    ----------
    p : dictionary
        A dictionary of the benchmark bicycle parameters. Make sure your units
        are correct, best to ue the benchmark paper's units!

    Returns
    -------
    M : ndarray, shape(2,2)
        The mass matrix.
    C1 : ndarray, shape(2,2)
        The damping like matrix that is proportional to the speed, v.
    K0 : ndarray, shape(2,2)
        The stiffness matrix proportional to gravity, g.
    K2 : ndarray, shape(2,2)
        The stiffness matrix proportional to the speed squared, v**2.

    Notes
    -----
    This function handles parameters with uncertanties.

    '''
    mT = p['mR'] + p['mB'] + p['mH'] + p['mF']
    xT = (p['xB'] * p['mB'] + p['xH'] * p['mH'] + p['w'] * p['mF']) / mT
    zT = (-p['rR'] * p['mR'] + p['zB'] * p['mB'] +
          p['zH'] * p['mH'] - p['rF'] * p['mF']) / mT

    ITxx = (p['IRxx'] + p['IBxx'] + p['IHxx'] + p['IFxx'] + p['mR'] *
            p['rR']**2 + p['mB'] * p['zB']**2 + p['mH'] * p['zH']**2 + p['mF']
            * p['rF']**2)
    ITxz = (p['IBxz'] + p['IHxz'] - p['mB'] * p['xB'] * p['zB'] -
            p['mH'] * p['xH'] * p['zH'] + p['mF'] * p['w'] * p['rF'])
    p['IRzz'] = p['IRxx']
    p['IFzz'] = p['IFxx']
    ITzz = (p['IRzz'] + p['IBzz'] + p['IHzz'] + p['IFzz'] +
            p['mB'] * p['xB']**2 + p['mH'] * p['xH']**2 + p['mF'] * p['w']**2)

    mA = p['mH'] + p['mF']
    xA = (p['xH'] * p['mH'] + p['w'] * p['mF']) / mA
    zA = (p['zH'] * p['mH'] - p['rF']* p['mF']) / mA

    IAxx = (p['IHxx'] + p['IFxx'] + p['mH'] * (p['zH'] - zA)**2 +
            p['mF'] * (p['rF'] + zA)**2)
    IAxz = (p['IHxz'] - p['mH'] * (p['xH'] - xA) * (p['zH'] - zA) + p['mF'] *
            (p['w'] - xA) * (p['rF'] + zA))
    IAzz = (p['IHzz'] + p['IFzz'] + p['mH'] * (p['xH'] - xA)**2 + p['mF'] *
            (p['w'] - xA)**2)
    uA = (xA - p['w'] - p['c']) * umath.cos(p['lam']) - zA * umath.sin(p['lam'])
    IAll = (mA * uA**2 + IAxx * umath.sin(p['lam'])**2 +
            2 * IAxz * umath.sin(p['lam']) * umath.cos(p['lam']) +
            IAzz * umath.cos(p['lam'])**2)
    IAlx = (-mA * uA * zA + IAxx * umath.sin(p['lam']) + IAxz *
            umath.cos(p['lam']))
    IAlz = (mA * uA * xA + IAxz * umath.sin(p['lam']) + IAzz *
            umath.cos(p['lam']))

    mu = p['c'] / p['w'] * umath.cos(p['lam'])

    SR = p['IRyy'] / p['rR']
    SF = p['IFyy'] / p['rF']
    ST = SR + SF
    SA = mA * uA + mu * mT * xT

    Mpp = ITxx
    Mpd = IAlx + mu * ITxz
    Mdp = Mpd
    Mdd = IAll + 2 * mu * IAlz + mu**2 * ITzz
    M = np.array([[Mpp, Mpd], [Mdp, Mdd]])

    K0pp = mT * zT # this value only reports to 13 digit precision it seems?
    K0pd = -SA
    K0dp = K0pd
    K0dd = -SA * umath.sin(p['lam'])
    K0 = np.array([[K0pp, K0pd], [K0dp, K0dd]])

    K2pp = 0.
    K2pd = (ST - mT * zT) / p['w'] * umath.cos(p['lam'])
    K2dp = 0.
    K2dd = (SA + SF * umath.sin(p['lam'])) / p['w'] * umath.cos(p['lam'])
    K2 = np.array([[K2pp, K2pd], [K2dp, K2dd]])

    C1pp = 0.
    C1pd = (mu*ST + SF*umath.cos(p['lam']) + ITxz / p['w'] *
            umath.cos(p['lam']) - mu*mT*zT)
    C1dp = -(mu * ST + SF * umath.cos(p['lam']))
    C1dd = (IAlz / p['w'] * umath.cos(p['lam']) + mu * (SA +
            ITzz / p['w'] * umath.cos(p['lam'])))
    C1 = np.array([[C1pp, C1pd], [C1dp, C1dd]])

    return M, C1, K0, K2
 def lam_equality(lam, rF, rR, a, b, c):
     return umath.sin(lam) - (rF - rR + c * umath.cos(lam)) / (a + b)
Exemple #44
0
def test_math_module():
    "Operations with the math module"

    x = ufloat(-1.5, 0.1)
    
    # The exponent must not be differentiated, when calculating the
    # following (the partial derivative with respect to the exponent
    # is not defined):
    assert (x**2).nominal_value == 2.25

    # Regular operations are chosen to be unchanged:
    assert isinstance(umath.sin(3), float)

    # factorial() must not be "damaged" by the umath module, so as 
    # to help make it a drop-in replacement for math (even though 
    # factorial() does not work on numbers with uncertainties 
    # because it is restricted to integers, as for 
    # math.factorial()):
    assert umath.factorial(4) == 24

    # fsum is special because it does not take a fixed number of
    # variables:
    assert umath.fsum([x, x]).nominal_value == -3

    # Functions that give locally constant results are tested: they
    # should give the same result as their float equivalent:
    for name in umath.locally_cst_funcs:

        try:
            func = getattr(umath, name)
        except AttributeError:
            continue  # Not in the math module, so not in umath either
        
        assert func(x) == func(x.nominal_value)
        # The type should be left untouched. For example, isnan()
        # should always give a boolean:
        assert type(func(x)) == type(func(x.nominal_value))

    # The same exceptions should be generated when numbers with uncertainties
    # are used:

    ## !! The Nose testing framework seems to catch an exception when
    ## it is aliased: "exc = OverflowError; ... except exc:..."
    ## surprisingly catches OverflowError. So, tests are written in a
    ## version-specific manner (until the Nose issue is resolved).

    try:
        math.log(0)
    except ValueError as err_math:
        # Python 3 does not make exceptions local variables: they are
        # restricted to their except block:
        err_math_args = err_math.args
    else:
        raise Exception('ValueError exception expected')

    try:
        umath.log(0)
    except ValueError as err_ufloat:
        assert err_math_args == err_ufloat.args
    else:
        raise Exception('ValueError exception expected')
    try:
        umath.log(ufloat(0, 0))
    except ValueError as err_ufloat:
        assert err_math_args == err_ufloat.args
    else:
        raise Exception('ValueError exception expected')
    try:
        umath.log(ufloat(0, 1))
    except ValueError as err_ufloat:
        assert err_math_args == err_ufloat.args
    else:
        raise Exception('ValueError exception expected')
Exemple #45
0
def BMSim(ParD, wrf, w1, time, dec_err=0.0, dec_mc=500, rho_err=0.0, rho_mc=500):
    # Numpy array to store mag vectors
    magVecs = zeros(13)
    # Numpy array to store eigenvalues
    eigVals = zeros(9)
    # Decay sim flag - 2pt or monoexp fit
    decFlag = False
    # Check to see if vdlist is defined
    if len(time) > 2:
        decFlag = True
        kR1p = 2.
        tmax = 1./kR1p
    else:
        kR1p = 2.
        # Estimate maximum Trelax needed to efficiently calculate a 2-point exponential decay
        #  Use known R1rho value if it is given, as 1/R1p will give int decay to ~0.36  
        if kR1p is not None:
            tmax = 1./kR1p

    # Unpack Parameters
    pB,pC,dwB,dwC = ParD['pb'], ParD['pc'], ParD['dwb'], ParD['dwc']
    kexAB,kexAC,kexBC = ParD['kexab'], ParD['kexac'], ParD['kexbc']
    R1,R1b,R1c = ParD['r1'], ParD['r1b'], ParD['r1c']
    R2,R2b,R2c = ParD['r2'], ParD['r2b'], ParD['r2c']
    lf, AlignMag = ParD['lf'], ParD['alignmag']
    pA = 1. - (pB + pC)

    ################################
    ##### Pre-run Calculations #####
    ################################
    # Convert w1, wrf to rad/sec from Hz
    w1 = w1 * 2. * pi
    wrf = wrf * 2. * pi
    #Convert dw from ppm to rad/s
    dwB = dwB * lf * 2. * pi # dw(ppm) * base-freq (eg 151 MHz, but just 151) * 2PI, gives rad/s
    dwC = dwC * lf * 2. * pi
    #Define forward/backward exchange rates
    k12 = kexAB * pB / (pB + pA)
    k21 = kexAB * pA / (pB + pA)
    k13 = kexAC * pC / (pC + pA)
    k31 = kexAC * pA / (pC + pA)
    if kexBC != 0.:
        k23 = kexBC * pC / (pB + pC)
        k32 = kexBC * pB / (pB + pC)
    else:
        k23 = 0.
        k32 = 0.

    # Calculate pertinent frequency offsets/etc for alignment and projection
    lOmegaA, lOmegaB, lOmegaC, uOmega1, uOmega2, uOmega3, uOmegaAvg,\
    delta1, delta2, delta3, deltaAvg, theta1, theta2, theta3, thetaAvg = \
                            AlignMagVec(w1, wrf, pA, pB, pC, dwB, dwC, kexAB, kexAC, kexBC, AlignMag)
    #Calculate initial magnetization
    Ma = pA*lOmegaA # GS
    Mb = pB*lOmegaB # ES1
    Mc = pC*lOmegaC # ES2

    # Magnetization matrix
    Ms = MatrixBM3(k12,k21,k13,k31,k23,k32,delta1,delta2,delta3,
                   w1, R1, R2, R1b, R1c, R2b, R2c)

    # Initial magnetization of GS (Ma), ES1 (Mb), ES2 (Mc)
    M0 = array([Ma[0],Mb[0],Mc[0],Ma[1],Mb[1],Mc[1],Ma[2],Mb[2],Mc[2]], float64)

    #################################################################
    #### Calculate Evolution of Magnetization for Fitting Func ######
    #################################################################

    if decFlag == True:
        # Calculate evolving magnetization at a given time increment
        # Returns array of projected magnetizations and indv components of mag
        # Col0 = Peff - mag projected along average
        # Col1 = Peff_err, if any
        # Col2,3,4 = PeffA,B,C - Projected along respective states
        # Col5,6,7 = Mxa, Mya, Mza
        # Col8,9,10 = Mxb, Myb, Mzb
        # Col11,12,13 = Mxc, Myc, Mzc
        # Col14 = time
        magVecs = asarray([SimMagVecs(x,M0,Ms,lOmegaA,lOmegaB,lOmegaC,w1,wrf) for x in time])
        # Append time to vectors
        magVecs = append(magVecs, time[:,None], axis=1)
        
        ## -- Monoexp Decay Error Corruption -- ##
        if dec_err != 0.0:
            # MC error number
            mcnum = dec_mc
            err = magVecs[:,0].max() * dec_err
            # Get normal distributions given error scaled to max int value
            # Generates a 2xN array of error corrupted Peff and Peff_err given
            #  a normal fit to the mcnum of random values
            # tp = array([normDist.fit(normal(x, err, size=mcnum)) for x in magVecs[:,0]])
            tp = array([normal(x, err, size=mcnum) for x in magVecs[:,0]])
             # Get mu and sigma for plots
            #  Get mu from first random normal selection of Peff values
            magVecs[:,0] = tp[:,0]
            # magVecs[:,0] = tp.mean(axis=1)
            magVecs[:,1] = tp.std(axis=1)

        # Calculate eigenvalues for export
        # append offset and slp (Hz) to front of eigenvalues
        eigVals = array([wrf/(2.*pi), w1/(2.*pi)])
        eigVals = append(eigVals, matrix_exponential(Ms, w1, wrf, 0.0, EigVal=True)[1])

        # If mag vecs are not nan
        if not isnan(magVecs.sum()):
            ## -- Monoexp fitting -- ##
            # If decay noise corruption non-zero, noise corrupt fitted R1rhos
            if dec_err != 0.0:
                # Weighted fit to get best R1rho value
                popt, pcov = curve_fit(ExpDecay, time, magVecs[:,0], (1., R1), sigma=magVecs[:,1])
                # MC error generation of R1ho from noise corrupted intensities
                popts = array([curve_fit(ExpDecay, time, x, (1., R1))[0] for x in tp.T])
                preExp, R1p, R1p_err = popt[0], popt[1], popts.std(axis=0)[1]

            # If no decay corruption, simply fit for R1rho
            else:
                popt, pcov = curve_fit(ExpDecay, time, magVecs[:,0], (1., R1))
                R1p = popt[1]
                R1p_err = 0.0
                preExp = popt[0]

        else:
            R1p = 0.0
            R1p_err = 0.0
            preExp = 1.
    else:
        # Calculate effective magnetization at Tmax and Tmin, respectively
        #  Returns floats corresponding to magnetization projected back along Meff at time T   
        magMin,magMax = AltCalcMagT(tmax,M0,Ms,lOmegaA,lOmegaB,lOmegaC,w1,wrf),\
                        AltCalcMagT(time[0],M0,Ms,lOmegaA,lOmegaB,lOmegaC,w1,wrf)

        # Check to make sure magnetization at Tmax is not <= 0, would give errorneous result
        if magMin <= 0.:
            # Project magnetization along average state in Jameson way
            #   Note: this PeffVec + Fit Exp gives nearly identical
            #         values to Flag 2 way
            PeffVec = asarray([AltCalcMagT(x,M0,Ms,lOmegaA,lOmegaB,lOmegaC,w1,wrf) for x in time])
            popt, pcov = curve_fit(ExpDecay,
                                   time,
                                   PeffVec,
                                   (1., 5.))
            R1p = popt[1]

        ## R1rho Calc Opt #1
        # Kay method (Korhznev, JACS, 2004) Solve with 2-pts
        # R1rho = -1/Tmax*ln(I1/I0), where I1 is Peff at Tmax
        #   NOTE: If use this, don't calc Peff above
        # Kay Method with Jameson Alt. Calc. Mag. T
        else:
            # If magnetization at Tmax is < 0,
            # Means odd exponential decay
            # In this case, walk backwards along time vector
            #  until the time where magMin(t) > 0
            #  Then solve for R1rho with new min magnetization
            R1p = -1./tmax*log(magMin/magMax)

    if isnan(R1p) == True:
        return array([0., 0., 1.]), magVecs, eigVals
    # If R1p is not NaN
    else:
        ## -- R1rho Direct Error Corruption -- ##
        if rho_err != 0.:
            tv = normal(R1p, R1p*rho_err, size=rho_mc)
            # Pick mean R1rho from first random normal distribution
            R1p = tv[0]
            R1p_err = tv.std()

        # Calculate R2eff - take on-res in to account
        # If on-resonance, thetaAvg = pi/2
        if deltaAvg == 0.: thetaAvg = pi/2.
        # Propagate error in R2eff, if applicable
        if R1p_err == 0.0:
            R2eff = (R1p/sin(thetaAvg)**2.) - (R1/(tan(thetaAvg)**2.))
            R2eff_err = 0.0
        else:
            R2eff = (ufloat(R1p, R1p_err)/umath.sin(thetaAvg)**2.) - (R1/(umath.tan(thetaAvg)**2.))
            R2eff_err = R2eff.std_dev
            R2eff = R2eff.n

        return array([R1p, R1p_err, R2eff, R2eff_err, preExp]), magVecs, eigVals
Exemple #46
0
def SolveProblem(d):
    # Get our needed variables
    for k in d["vars"]:
        if k in set(("S1", "S2", "S3", "A1", "A2", "A3")):
            exec("%s = d['vars']['%s']" % (k, k))
    angle_conv = d["angle_measure"]  # Converts angle measure to radians
    prob = d["problem_type"]
    try:
        if prob == "sss":
            # Law of cosines to find two angles, angle law to find third.
            A1 = acos((S2**2 + S3**2 - S1**2)/(2*S2*S3))
            A2 = acos((S1**2 + S3**2 - S2**2)/(2*S1*S3))
            A3 = pi - A1 - A2
        elif prob == "ssa":
            # Law of sines to find the other two angles and remaining
            # side.  Note it can have two solutions (the second solution's
            # data will be in the variables s1_2, s2_2, etc.).
            A1 *= angle_conv  # Make sure angle is in radians
            A2 = asin((S2/S1*sin(A1)))
            A3 = pi - A1 - A2
            S3 = S2*sin(A3)/sin(A2)
            # Check for other solution
            A1_2 = A1
            A2_2 = pi - A2
            A3_2 = pi - A1_2 - A2_2
            if A1_2 + A2_2 + A3_2 > pi:
                # Second solution not possible
                del A1_2
                del A2_2
                del A3_2
            else:
                # Second solution is possible
                S1_2 = S1
                S2_2 = S2
                S3_2 = S2_2*sin(A3_2)/sin(A2_2)
        elif prob == "sas":
            # Law of cosines to find third side; law of sines to find
            # another angle; angle law for other angle.  Note we rename
            # the incoming angle to be consistent with a solution diagram.
            A3 = A1*angle_conv  # Make sure angle is in radians
            S3 = sqrt(S1**2 + S2**2 - 2*S1*S2*cos(A3))
            A2 = asin(S2*sin(A3)/S3)
            A1 = pi - A2 - A3
        elif prob == "asa":
            # Third angle from angle law; law of sines for other two
            # sides.  Note we rename the sides for consistency with a
            # diagram.
            A1 *= angle_conv  # Make sure angle is in radians
            A2 *= angle_conv  # Make sure angle is in radians
            A3 = pi - A1 - A2
            S3 = S1
            S2 = S3*sin(A2)/sin(A3)
            S1 = S3*sin(A1)/sin(A3)
        elif prob == "saa":
            # Third angle from angle law; law of sines for other two
            # sides. 
            A1 *= angle_conv  # Make sure angle is in radians
            A2 *= angle_conv  # Make sure angle is in radians
            A3 = pi - A1 - A2
            S2 = S1*sin(A2)/sin(A1)
            S3 = S1*sin(A3)/sin(A1)
        else:
            raise ValueError("Bug:  unrecognized problem")
    except UnboundLocalError as e:
        s = str(e)
        loc = s.find("'")
        s = s[loc + 1:]
        loc = s.find("'")
        s = s[:loc]
        Error("Variable '%s' not defined" % s)
    except ValueError as e:
        msg = "Can't solve the problem:\n"
        msg += "  Error:  %s" % str(e)
        Error(msg)
    # Collect solution information
    solution = {}
    vars = set((
        "S1", "S2", "S3", "A1", "A2", "A3",
        "S1_2", "S2_2", "S3_2", "A1_2", "A2_2", "A3_2",
    ))
    for k in vars:
        if k in locals():
            exec("solution['%s'] = %s" % (k, k))
    d["solution"] = solution
Exemple #47
0
def Test():
    '''The following test cases came from the sample problems at
    http://www.mathsisfun.com/algebra/trig-solving-triangles.html
    '''
    eps, r2d, d2r = 1e-14, 180/pi, pi/180
    d = {
        "angle_measure" : d2r,
    }
    # sss
    d["vars"] = {
        "S1" : 6,
        "S2" : 7,
        "S3" : 8,
    }
    d["problem_type"] = "sss"
    SolveProblem(d)
    k = d["solution"]
    assert abs(k["A1"] - acos(77/112)) < eps
    assert abs(k["A2"] - (pi - k["A3"] - k["A1"])) < eps
    assert abs(k["A3"] - acos(1/4)) < eps
    # ssa
    d["vars"] = {
        "S1" : 8,
        "S2" : 13,
        "A1" : 31,  # Angle in degrees
    }
    d["problem_type"] = "ssa"
    SolveProblem(d)
    k = d["solution"]
    a2 = asin(13*sin(31*d2r)/8)
    assert abs(k["A2"] - a2) < eps
    a3 = pi - k["A2"] - k["A1"]
    assert abs(k["A3"] - a3) < eps
    assert abs(k["S3"] - sin(a3)*8/sin(31*d2r)) < eps
    # Check other solution
    a2_2 = pi - asin(13*sin(31*d2r)/8)
    assert abs(k["A2_2"] - a2_2) < eps
    a3_2 = pi - k["A2_2"] - k["A1_2"]
    assert abs(k["A3_2"] - a3_2) < eps
    assert abs(k["S3_2"] - sin(a3_2)*8/sin(31*d2r)) < eps
    # sas
    d["vars"] = {
        "S1" : 5,
        "S2" : 7,
        "A1" : 49,  # Angle in degrees
    }
    d["problem_type"] = "sas"
    SolveProblem(d)
    k = d["solution"]
    # asa
    d["vars"] = {
        "S1" : 9,
        "A1" : 76,  # Angle in degrees
        "A2" : 34,  # Angle in degrees
    }
    d["problem_type"] = "asa"
    SolveProblem(d)
    k = d["solution"]
    assert abs(k["S2"] - 9*sin(34*d2r)/sin(70*d2r)) < eps
    assert abs(k["S1"] - 9*sin(76*d2r)/sin(70*d2r)) < eps
    assert abs(k["A3"] - 70*d2r) < eps
    # saa
    d["vars"] = {
        "S1" : 7,
        "A1" : 62,  # Angle in degrees
        "A2" : 35,  # Angle in degrees
    }
    d["problem_type"] = "saa"
    SolveProblem(d)
    k = d["solution"]
    assert abs(k["A3"] - 83*d2r) < eps
    assert abs(k["S2"] - 7*sin(35*d2r)/sin(62*d2r)) < eps
    assert abs(k["S3"] - 7*sin(83*d2r)/sin(62*d2r)) < eps
    out("Tests passed")
Exemple #48
0
 def sin(self):
     if self.unit.is_angle:
         return unp.sin(self.value *
                        self.unit.conversion_factor_to(_unit_table['rad']))
     else:
         raise UnitError('Argument of sin must be an angle')