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
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)
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)
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 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
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')
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
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))
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
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)) ) )