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)
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 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
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 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
def dOmega(theta_cm, n): """ function to find dΩcm/dΩlab 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 ------ dΩcm/dΩlab : factor to convert differential cross-section in the center-of-mass system to one in the lab system Notice ------ This function does not consider relativity """ if isinstance(theta_cm, uncertainties.core.AffineScalarFunc): return umath.pow(1.0 + 2.0 * umath.cos(theta_cm) / n + 1.0 / n**2.0, 3 / 2) \ / (1.0 + umath.cos(theta_cm) / n) elif isinstance(theta_cm, np.ndarray) and isinstance( theta_cm[0], uncertainties.core.AffineScalarFunc): return unp.pow(1.0 + 2.0 * unp.cos(theta_cm) / n + 1.0 / n**2.0, 3 / 2) \ / (1.0 + unp.cos(theta_cm) / n) else: return np.power(1.0 + 2.0 * np.cos(theta_cm) / n + 1.0 / n**2.0, 3 / 2) \ / (1.0 + np.cos(theta_cm) / n)
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)])
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), ])
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.")
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 theta(self, a): """ Arguments --------- a : angle of rotation [rad] Return ------ θ : scattering angle in the lab system [rad] """ D0 = self.D(0.0) D = self.D(a) Rd = self.R + self.d if isinstance(a, (int, float, np.number, uncertainties.core.AffineScalarFunc)): return np.sign(a) * umath.acos( (D0**2.0 + D**2.0 - 2.0 * Rd**2.0 * (1.0 - umath.cos(a))) / (2.0 * D0 * D) ) elif isinstance(a, np.ndarray): return np.sign(a) * unp.arccos( (D0**2.0 + D**2.0 - 2.0 * Rd**2.0 * (1.0 - unp.cos(a))) / (2.0 * D0 * D) ) else: raise ValueError( f"This function not supported for the input types. argument 'a' must be number or array")
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 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)))
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), ])
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)
def getRaDec(self,epoch): epoch_0 = Time(self._epoch_0,format='jyear',scale='tcb') epoch = Time(epoch,format='jyear',scale='tcb') dt = epoch.jyear - epoch_0.jyear if self._parallax == None: dec_0_rad = self._dec_0 * self.DEG_TO_RAD dec = self._dec_0 + dt * self._pmdec * self.MAS_TO_DEG ra = self._ra_0 + dt * (self._pmra / np.cos(dec_0_rad)) * self.MAS_TO_DEG return numpy.array([ra,dec]) else: parallaxAU = p.parallax_to_au(self._parallax) R_0 = p.angular_to_cartesian(self._ra_0,self._dec_0) * parallaxAU _m = p.get_motion_vector(self._ra_0,self._dec_0, self._pmra,self._pmdec,self._parallax) R_earth = p.get_earth_observer_vector(epoch) R = R_0 + (_m* dt) - R_earth #This was used to test against astropy #Rcoord = SkyCoord((R[0]).n,(R[1]).n,(R[2]).n, frame='icrs', unit='AU', representation='cartesian') #Rcoord.representation = 'spherical' #return numpy.array([Rcoord.ra.degree,Rcoord.dec.degree]) return p.cartesian_to_angular(R[0],R[1],R[2])
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])
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_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 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
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 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 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
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
def basic_dipole_monopole(amplitude=DIP_AMPLITUDE, \ theta=THETA, \ monopole=DIP_MONOPOLE, \ *args, \ **kwargs): """Returns the predicted value of da/a as given by eq. 15 in King et al. 2012. Arguments: :param amplitude: Amplitude of dipole. :type amplitude: number :param theta: angle in radians between the dipole and a positions on the sky. :type theta: number :param monopole: monopole term. :type monopole: number :returns: value of predicted dipole at a theta radians away from dipole. :rtype: number """ return amplitude * umath.cos(theta) + monopole
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 basic_r_dipole_monopole(amplitude=R_DIPOLE_AMPLITUDE,\ radial_distance=RADIAL_DISTANCE,\ theta=THETA,\ monopole=R_DIPOLE_MONOPOLE,\ *args,\ **kwargs): """ Arguments: :param amplitude: Amplitude term of dipole (optional with uncertainty via uncertainties.ufloat((value, error)) ). :type amplitude: number :param radial_distance: Radial distance in GLyr :type radial_distance: number :type theta: number :param monopole: monopole term. :type monopole: number returns """ return amplitude * radial_distance * umath.cos(theta) + monopole
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
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
def D(self, a): """ Arguments --------- a : angle of rotation [rad] Return ------ D : distance between target and detector [mm] """ Rd = self.R + self.d r = self.r AT = self.AT if isinstance(a, (int, float, np.number, uncertainties.core.AffineScalarFunc)): return umath.sqrt(Rd**2.0 + r**2.0 - 2.0 * Rd * r * umath.cos(a + AT)) elif isinstance(a, np.ndarray): return unp.sqrt(Rd**2.0 + r**2.0 - 2.0 * Rd * r * unp.cos(a + AT)) else: raise ValueError( f"This function not supported for the input types. argument 'a' must be number or array")
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 effective_ringed_planet_radius(rp, rin, rout, ir): """ Calculate effective radius of a ringed planet accounting for possible overlap between ring and planet. - eqn (2) from zuluaga+2015 http://dx.doi.org/10.1088/2041-8205/803/1/L14 Parameters: ----------- rp : float, ufloat; Radius of the planet hosting the ring rin, rout : float, ufloat; Inner and outer radii of the ring in units of rp. ir : float, ufloat; Inclination of the ring from the skyplane. 0 is face-on ring, 90 is edge on Returns: -------- eff_R : float, ufloat; effective radius of the ringed planet in same unit as rp """ cosir = cos(radians(ir)) sinir = sin(radians(ir)) y = lambda r: sqrt(r**2 - 1) / (r * sinir) def eff(r): if r * cosir > 1: eff_r = r**2 * cosir - 1 else: eff_r = (r**2 * cosir * 2 / np.pi * asin(y(r))) - (2 / np.pi * asin(y(r) * r * cosir)) return eff_r rout_eff2 = eff(rout) rin_eff2 = eff(rin) Arp = rp**2 + rp**2 * (rout_eff2 - rin_eff2) return sqrt(Arp)
def get_dcsd_correction(): from uncertainties import ufloat, umath corr = [] dz_modes = [(i, j) for i in [0, 1, 3] for j in [0, 1, 3]] for i, j in dz_modes: r_i_val = modes[i]['amplitude ratio'] r_j_val = modes[j]['amplitude ratio'] r_i_err = modes[i]['amplitude ratio err'] r_j_err = modes[j]['amplitude ratio err'] r_i = ufloat((r_i_val, r_i_err)) r_j = ufloat((r_j_val, r_j_err)) delta_i_val = modes[i]['phase'] delta_j_val = modes[j]['phase'] delta_i_err = modes[i]['phase err'] delta_j_err = modes[j]['phase err'] delta_i = ufloat((delta_i_val, delta_i_err)) delta_j = ufloat((delta_j_val, delta_j_err)) R_i_val = modes[i]['coherence factor'] R_j_val = modes[j]['coherence factor'] R_i_err = modes[i]['coherence factor err'] R_j_err = modes[j]['coherence factor err'] R_i = ufloat((R_i_val, R_i_err)) R_j = ufloat((R_i_val, R_i_err)) correction = 1 - 2 * r_i * r_j * umath.cos(delta_i + delta_j) + r_i**2 * r_j**2 yield_factor = 1 / correction corr.append(str(yield_factor)) return corr
def get_dcsd_correction(): from uncertainties import ufloat, umath corr = [] dz_modes = [(i,j) for i in [0,1,3] for j in [0,1,3]] for i,j in dz_modes: r_i_val = modes[i]['amplitude ratio'] r_j_val = modes[j]['amplitude ratio'] r_i_err = modes[i]['amplitude ratio err'] r_j_err = modes[j]['amplitude ratio err'] r_i = ufloat((r_i_val, r_i_err)) r_j = ufloat((r_j_val, r_j_err)) delta_i_val = modes[i]['phase'] delta_j_val = modes[j]['phase'] delta_i_err = modes[i]['phase err'] delta_j_err = modes[j]['phase err'] delta_i = ufloat((delta_i_val, delta_i_err)) delta_j = ufloat((delta_j_val, delta_j_err)) R_i_val = modes[i]['coherence factor'] R_j_val = modes[j]['coherence factor'] R_i_err = modes[i]['coherence factor err'] R_j_err = modes[j]['coherence factor err'] R_i = ufloat((R_i_val, R_i_err)) R_j = ufloat((R_i_val, R_i_err)) correction = 1 - 2*r_i*r_j*umath.cos( delta_i + delta_j ) + r_i**2 * r_j**2 yield_factor = 1/correction corr.append(str(yield_factor)) return corr
def calculate_l1_l2(h6, h7, d5, d6, l): '''Returns the distance along (l2) and perpendicular (l1) to the steer axis from the front wheel center to the handlebar reference point. Parameters ---------- h6 : float Distance from the table to the top of the front axle. h7 : float Distance from the table to the top of the handlebar reference circle. d5 : float Diameter of the front axle. d6 : float Diameter of the handlebar reference circle. l : float Outer distance from the front axle to the handlebar reference circle. Returns ------- l1 : float The distance from the front wheel center to the handlebar reference center perpendicular to the steer axis. The positive sense is if the handlebar reference point is more forward than the front wheel center relative to the steer axis normal. l2 : float The distance from the front wheel center to the handlebar reference center parallel to the steer axis. The positive sense is if the handlebar reference point is above the front wheel center with reference to the steer axis. ''' r5 = d5 / 2. r6 = d6 / 2. l1 = h7 - h6 + r5 - r6 l0 = l - r5 - r6 gamma = umath.asin(l1 / l0) l2 = l0 * umath.cos(gamma) return l1, l2
def basic_z_dipole_monopole(prefactor=Z_DIP_PREFACTOR, \ z_redshift=REDSHIFT, \ beta=Z_DIP_BETA, \ theta=THETA, \ monopole=Z_DIP_MONOPOLE,\ *args,\ **kwargs): """ Arguments: :param prefactor: Amplitude of dipole. :type prefactor: number :param z_redshift: Redshift of absorber in sky. :type z_redshift: number :param beta: power law exponent. :type beta: number :param theta: angle in radians between the dipole and a positions on the sky. :type theta: number :param monopole: monopole term. :type monopole: number :returns: value of predicted dipole at a theta radians away from dipole. :rtype: number """ return prefactor * z_redshift ** beta * umath.cos(theta) + monopole
def cos(self): if self.unit.is_angle: return unp.cos(self.value * self.unit.conversion_factor_to(_unit_table['rad'])) else: raise UnitError('Argument of cos must be an angle')
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
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)