Exemple #1
0
def com_line(alpha, a, par, part, l1, l2):
    '''Returns the slope and intercept for the line that passes through the
    part's center of mass with reference to the benchmark bicycle coordinate
    system.

    Parameters
    ----------
    alpha : float
        The angle the head tube makes with the horizontal. When looking at the
        bicycle from the right side this is the angle between a vector point
        out upwards along the steer axis and the earth horizontal with the
        positve direction pointing from the left to the right. If the bike is
        in its normal configuration this would be 90 degrees plus the steer
        axis tilt (lambda).
    a : float
        The distance from the pendulum axis to a reference point on the part,
        typically the wheel centers. This is positive if the point falls to the
        left of the axis and negative otherwise.
    par : dictionary
        Benchmark parameters. Must include lam, rR, rF, w
    part : string
        The subscript denoting which part this refers to.
    l1, l2 : floats
        The location of the handlebar reference point relative to the front
        wheel center when the fork is split. This is measured perpendicular to
        and along the steer axis, respectively.

    Returns
    -------
    m : float
        The slope of the line in the benchmark coordinate system.
    b : float
        The z intercept in the benchmark coordinate system.

    '''

    # beta is the angle between the x bike frame and the x pendulum frame, rotation
    # about positive y
    beta = par['lam'] - alpha * pi / 180

    # calculate the slope of the center of mass line
    m = -umath.tan(beta)

    # calculate the z intercept
    # this the bicycle frame
    if part == 'B':
        b = -a / umath.cos(beta) - par['rR']
    # this is the fork (without handlebar) or the fork and handlebar combined
    elif part == 'S' or part == 'H':
        b = -a / umath.cos(beta) - par['rF'] + par['w'] * umath.tan(beta)
    # this is the handlebar (without fork)
    elif part == 'G':
        u1, u2 = fwheel_to_handlebar_ref(par['lam'], l1, l2)
        b = -a / umath.cos(beta) - (par['rF'] +
                                    u2) + (par['w'] - u1) * umath.tan(beta)
    else:
        print part, "doesn't exist"
        raise KeyError

    return m, b, beta
Exemple #2
0
def com_line(alpha, a, par, part, l1, l2):
    '''Returns the slope and intercept for the line that passes through the
    part's center of mass with reference to the benchmark bicycle coordinate
    system.

    Parameters
    ----------
    alpha : float
        The angle the head tube makes with the horizontal. When looking at the
        bicycle from the right side this is the angle between a vector point
        out upwards along the steer axis and the earth horizontal with the
        positve direction pointing from the left to the right. If the bike is
        in its normal configuration this would be 90 degrees plus the steer
        axis tilt (lambda).
    a : float
        The distance from the pendulum axis to a reference point on the part,
        typically the wheel centers. This is positive if the point falls to the
        left of the axis and negative otherwise.
    par : dictionary
        Benchmark parameters. Must include lam, rR, rF, w
    part : string
        The subscript denoting which part this refers to.
    l1, l2 : floats
        The location of the handlebar reference point relative to the front
        wheel center when the fork is split. This is measured perpendicular to
        and along the steer axis, respectively.

    Returns
    -------
    m : float
        The slope of the line in the benchmark coordinate system.
    b : float
        The z intercept in the benchmark coordinate system.

    '''

    # beta is the angle between the x bike frame and the x pendulum frame, rotation
    # about positive y
    beta = par['lam'] - alpha * pi / 180

    # calculate the slope of the center of mass line
    m = -umath.tan(beta)

    # calculate the z intercept
    # this the bicycle frame
    if part == 'B':
        b = -a / umath.cos(beta) - par['rR']
    # this is the fork (without handlebar) or the fork and handlebar combined
    elif part == 'S' or part == 'H':
        b = -a / umath.cos(beta) - par['rF'] + par['w'] * umath.tan(beta)
    # this is the handlebar (without fork)
    elif part == 'G':
        u1, u2 = fwheel_to_handlebar_ref(par['lam'], l1, l2)
        b = -a / umath.cos(beta) - (par['rF'] + u2) + (par['w'] - u1) * umath.tan(beta)
    else:
        print part, "doesn't exist"
        raise KeyError

    return m, b, beta
Exemple #3
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 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 #5
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 #6
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 #7
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 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 #9
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 #10
0
 def tan(self):
     if self.unit.is_angle:
         return unp.tan(self.value *
                        self.unit.conversion_factor_to(_unit_table['rad']))
     else:
         raise UnitError('Argument of tan must be an angle')
Exemple #11
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)
    # print pB, pC
    # print kexAB, kexAC, kexBC
    # print dwB, dwC
    # print R1,R1b,R1c
    # print R2,R2b,R2c

    ################################
    ##### 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  # ES1
    Mb = pB * lOmegaB  # GS
    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 (Mb), ES1 (Ma), 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 - x-comps of indv states
        # 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 #12
0
def grid(path, name, key):
    metadata, data = read_nid(path)

    height, x, y = load_corrected_image(metadata, data, key=key)

    peaks = peak_local_max(
        height,
        min_distance=6,
    ).astype('float64')

    peaks[:, 0] = peaks[:, 0] * x.max() / height.shape[0]
    peaks[:, 1] = peaks[:, 1] * y.max() / height.shape[1]

    fig = plt.figure()
    ax = fig.add_subplot(1, 1, 1, aspect=1)
    plot = ax.pcolormesh(x, y, height, cmap='inferno')
    plot.set_rasterized(True)

    ax.plot(peaks[:, 1], peaks[:, 0], 'w.', ms=3)
    fig.colorbar(plot, ax=ax, label=r'$z \mathbin{/} \si{\nano\meter}$')

    # print(peaks)

    d1 = np.array([0, 0])
    diagonal_points = []
    for a in range(13):
        d1 = get_next_point_on_diagonal(d1, peaks)
        if len(d1) == 0:
            break
        diagonal_points.append(d1)

    diagonal_distances = np.array([
        distance.euclidean(a, b)
        for a, b in zip(diagonal_points[:-1], diagonal_points[1:])]
    )
    gd = ufloat(diagonal_distances.mean(), diagonal_distances.std())
    print('Gitterkonstante a_1: {}'.format(gd))

    diagonal_points = np.array(diagonal_points)
    x_coords = diagonal_points[:, 1]
    y_coords = diagonal_points[:, 0]
    popt, pcov = curve_fit(line, x_coords, y_coords)
    m, b = correlated_values(popt, pcov)
    xs = np.linspace(0, 2.44, 50)
    ax.plot(xs, line(xs, m.n, b.n), color='lightgray')
    angle_diagonal = umath.atan(m)
    # print(angle_diagonal)

    for d in diagonal_points:
        ax.plot(d[1], d[0], 'o', color='#46d7ff', alpha=0.7)

    d1 = [0.33,  0]
    horizontal_points = []
    for a in range(10):
        d1 = get_next_point_on_horizontal(d1, peaks)
        if len(d1) == 0:
            break
        horizontal_points.append(d1)

    for d in horizontal_points:
        ax.plot(d[1], d[0], 'o', color='#dfec56', alpha=0.7)

    horizontal_points = np.array(horizontal_points)
    x_coords = horizontal_points[:, 1]
    y_coords = horizontal_points[:, 0]
    popt, pcov = curve_fit(line, x_coords, y_coords)
    m, b = correlated_values(popt, pcov)
    angle_horizontal = umath.atan(m)
    angle = angle_diagonal - angle_horizontal

    # should be 60
    correction_factor = np.tan(np.pi/3)/umath.tan(angle)
    print('Gemessener Winkel ist {}. Soll ist 60. Korrekturfaktor ist {}'.format(
        rad2deg(angle), correction_factor
    ))
    ax.plot(xs, line(xs, m.n, b.n), color='lightgray')

    horizontal_distances = np.array([
        distance.euclidean(a, b)
        for a, b in zip(horizontal_points[:-1], horizontal_points[1:])
    ])
    gh = ufloat(horizontal_distances.mean(), horizontal_distances.std())
    print('Gitterkonstante a_2: {}'.format(gh))

    ax.set_xlim(0, x.max())
    ax.set_ylim(0, y.max())

    g_string = '\SI{{{:.3f} \pm {:.3f}}}{{\\nano\\meter}}'.format(gh.n, gh.s)
    with open('build/grid_constant_horizontal_{}.tex'.format(name), 'w') as f:
        f.write(g_string)

    g_string = r'$\num{{{:.2f} \pm {:.2f}}}$'.format(correction_factor.n, correction_factor.s)
    with open('build/correction_factor_{}.tex'.format(name), 'w') as f:
        f.write(g_string)


    g_string = '\SI{{{:.3f} \pm {:.3f}}}{{\\nano\\meter}}'.format(gd.n, gd.s)
    with open('build/grid_constant_diagonal_{}.tex'.format(name), 'w') as f:
        f.write(g_string)

    angle = angle_diagonal - angle_horizontal
    g_string = '\\ang{{{:.2f} \pm {:.2f}}}'.format(np.rad2deg(angle.n), np.rad2deg(angle.s))
    with open('build/grid_angle_{}.tex'.format(name), 'w') as f:
        f.write(g_string)

    # plt.show()
    ax.set_xlabel(r'$x \mathbin{/} \si{\nano\meter}$')
    ax.set_ylabel(r'$y \mathbin{/} \si{\nano\meter}$')
    fig.tight_layout(pad=0)
    fig.savefig('build/plots/hopg_{}.pdf'.format(name))
Exemple #13
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 #14
0
def mott(theta, T, Z, A, S):
    """
    Mott 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
    Z     : atomic number; charge in units of e
    A     : mass number
    S     : spin

    Return
    ------
    dσ/dΩ(θ) in the center-of-mass system [mb/str]
    """
    # rest energy
    mc2 = A * AMU
    # total energy of incident/target particle in the center-of-mass system
    Ecm = (T + 2.0 * mc2) / 2.0
    # gamma (= gamma_cm in this situattion)
    gamma = Ecm / mc2
    # beta (= beta_cm in this situattion)
    beta = np.sqrt(1.0 - 1.0 / gamma**2.0)
    # relative beta in the center-of-mass system
    brel = 2.0 * beta / (1.0 + beta**2.0)

    # dσ/dΩ[mb/str]
    # 10.0 : fm^2 --> mb
    if isinstance(theta, uncertainties.core.AffineScalarFunc):
        return 10.0 * (Z**2 * E2 / (4.0 * T))**2.0 * (
            umath.pow(umath.sin(theta / 2.0), -4.0)
            + umath.pow(umath.cos(theta / 2.0), -4.0)
            + (-1.0)**(2.0 * S) * 2.0 / (2.0 * S + 1.0) *
            umath.pow(umath.sin(theta / 2.0), -2.0) *
            umath.pow(umath.cos(theta / 2.0), -2.0) *
            umath.cos(Z**2.0 * E2 / (HBARC * brel) *
                      umath.log(umath.pow(umath.tan(theta / 2.0), 2.0))
                      )
        )
    elif isinstance(theta, np.ndarray) and isinstance(theta[0], uncertainties.core.AffineScalarFunc):
        return 10.0 * (Z**2 * E2 / (4.0 * T))**2.0 * (
            unp.pow(unp.sin(theta / 2.0), -4.0)
            + unp.pow(unp.cos(theta / 2.0), -4.0)
            + (-1.0)**(2.0 * S) * 2.0 / (2.0 * S + 1.0) *
            unp.pow(unp.sin(theta / 2.0), -2.0) *
            unp.pow(unp.cos(theta / 2.0), -2.0) *
            unp.cos(Z**2.0 * E2 / (HBARC * brel) *
                    unp.log(unp.pow(unp.tan(theta / 2.0), 2.0))
                    )
        )
    else:
        return 10.0 * (Z**2 * E2 / (4.0 * T))**2.0 * (
            np.power(np.sin(theta / 2.0), -4.0)
            + np.power(np.cos(theta / 2.0), -4.0)
            + (-1.0)**(2.0 * S) * 2.0 / (2.0 * S + 1.0) *
            np.power(np.sin(theta / 2.0), -2.0) *
            np.power(np.cos(theta / 2.0), -2.0) *
            np.cos(Z**2.0 * E2 / (HBARC * brel) *
                   np.log(np.power(np.tan(theta / 2.0), 2.0))
                   )
        )
Exemple #15
0
 def tan(self):
     if self.unit.is_angle:
         return unp.tan(self.value *
                        self.unit.conversion_factor_to(_unit_table['rad']))
     else:
         raise UnitError('Argument of tan must be an angle')