def getRhoHat(rah, ram, ras, dech, decm, decs): raRad = odlib.degreesToRadians(odlib.HMStoDeg(rah, ram, ras)) decRad = odlib.degreesToRadians(odlib.DMStoDeg(dech, decm, decs)) rhox = cos(raRad) * cos(decRad) rhoy = sin(raRad) * cos(decRad) rhoz = sin(decRad) return [rhox, rhoy, rhoz]
def getRhoHat(rah, ram, ras=0, dech=0, decm=0, decs=0): # First two elements will be RA (hr) and DEC (deg) if radecAsDecimal if radecAsDecimal: raRad = odlib.degreesToRadians(rah * 15) decRad = odlib.degreesToRadians(ram) else: raRad = odlib.degreesToRadians(odlib.HMStoDeg(rah, ram, ras)) decRad = odlib.degreesToRadians(odlib.DMStoDeg(dech, decm, decs)) rhox = cos(raRad) * cos(decRad) rhoy = sin(raRad) * cos(decRad) rhoz = sin(decRad) return np.array([rhox, rhoy, rhoz])
import odlib import numpy as np from math import sin, cos, sqrt, pi, asin a = 3.333373705525415 e = 0.6300217569592357 i = odlib.degreesToRadians(12.607673026103942) omega = odlib.degreesToRadians(232.6027678824531) w = odlib.degreesToRadians(50.817782977450406) M2 = odlib.degreesToRadians(1.6803544595919) t2 = 2458671.6550316783 # Change these for different dates t = 2458671.6550316783 eclipticObliquity = 23.4367540863 R = np.array( [-2.547806549329457E-01, 9.031163132855038E-01, 3.914640974482125E-01]) # Finds the value of E in the equation M = E + e * sin(E) # Uses Newton's method def newtonFindE(e, realM): # An initial guess E = realM # 100 was chosen arbitrarily, but it works for i in range(100): M = E - e * sin(E) derivM = 1 - e * cos(E) E = E - (M - realM) / derivM return E
def od(t1, t2, t3, ra1, dec1, ra2, dec2, ra3, dec3, R): tau3 = odlib.timeToGaussian(t3, t2) tau1 = odlib.timeToGaussian(t1, t2) tau0 = tau3 - tau1 realR2Dot = (realR3 - realR1) / tau0 if radecAsDecimal: rhoHat1 = getRhoHat(ra1, dec1) rhoHat2 = getRhoHat(ra2, dec2) rhoHat3 = getRhoHat(ra3, dec3) else: rhoHat1 = getRhoHat(*ra1, *dec1) rhoHat2 = getRhoHat(*ra2, *dec2) rhoHat3 = getRhoHat(*ra3, *dec3) a = [tau3 / tau0, -1, -tau1 / tau0] rhoHats = np.array([rhoHat1, rhoHat2, rhoHat3]) rho = rhoHats.copy() D0 = odlib.tri_product(rhoHat1, rhoHat2, rhoHat3) assert (D0 != 0) D1 = odlib.tri_product(rhoHat3, R[0], rhoHat2) D2 = odlib.tri_product(rhoHat3, R[1], rhoHat2) D3 = odlib.tri_product(rhoHat3, R[2], rhoHat2) rho[0] *= (a[0] * D1 + a[1] * D2 + a[2] * D3) / (a[0] * D0) D1 = odlib.tri_product(rhoHat3, rhoHat1, R[0]) D2 = odlib.tri_product(rhoHat3, rhoHat1, R[1]) D3 = odlib.tri_product(rhoHat3, rhoHat1, R[2]) rho[1] *= (a[0] * D1 + a[1] * D2 + a[2] * D3) / (a[1] * D0) D1 = odlib.tri_product(rhoHat1, rhoHat2, R[0]) D2 = odlib.tri_product(rhoHat1, rhoHat2, R[1]) D3 = odlib.tri_product(rhoHat1, rhoHat2, R[2]) rho[2] *= (a[0] * D1 + a[1] * D2 + a[2] * D3) / (a[2] * D0) r = rho - R r2Dot = (r[2] - r[0]) / tau0 tauAt1 = odlib.timeToGaussian(t1) tauAt2 = odlib.timeToGaussian(t2) tauAt3 = odlib.timeToGaussian(t3) def f(tau, tau2, r2, r2Dot): res = 1 - (tau - tau2)**2 / (2 * odlib.mag(r2)**3) res += odlib.dot(r2, r2Dot) / (2 * odlib.mag(r2)**5) * (tau - tau2)**3 O4 = 3 * (odlib.dot(r2Dot, r2Dot) / odlib.mag(r2)**2 - 1 / odlib.mag(r2)**3) O4 += -15 * (odlib.dot(r2, r2Dot) / odlib.mag(r2)**2)**2 + 1 / odlib.mag(r2)**3 O4 *= ((tau - tau2)**4 / (24 * odlib.mag(r2)**3)) return res + O4 def g(tau, tau2, r2, r2Dot): res = tau - tau2 - (tau - tau2)**3 / (6 * odlib.mag(r2)**3) res += (odlib.dot(r2, r2Dot) * (tau - tau2)**4) / (4 * odlib.mag(r2)**5) return res tiny = 1E-9 maxIterations = 200 iteration = 0 # Minus 100 so the loop doesn't exit immediately r2Old = r[1] - 100 r2DotOld = r2Dot while (np.any(abs(r[1] - r2Old) > tiny) or np.any(abs(r2Dot - r2DotOld) > tiny)) and iteration < maxIterations: r2Old = r[1].copy() r2DotOld = r2Dot.copy() if useLightspeedCorrection: # Lightspeed correction correctedT1 = t1 - odlib.mag(rho[0]) / c correctedT2 = t2 - odlib.mag(rho[1]) / c correctedT3 = t3 - odlib.mag(rho[2]) / c tauAt1 = odlib.timeToGaussian(correctedT1) tauAt2 = odlib.timeToGaussian(correctedT2) tauAt3 = odlib.timeToGaussian(correctedT3) rho = rhoHats.copy() D0 = odlib.tri_product(rhoHat1, rhoHat2, rhoHat3) assert (D0 != 0) D1 = odlib.tri_product(rhoHat3, R[0], rhoHat2) D2 = odlib.tri_product(rhoHat3, R[1], rhoHat2) D3 = odlib.tri_product(rhoHat3, R[2], rhoHat2) rho[0] *= (a[0] * D1 + a[1] * D2 + a[2] * D3) / (a[0] * D0) D1 = odlib.tri_product(rhoHat3, rhoHat1, R[0]) D2 = odlib.tri_product(rhoHat3, rhoHat1, R[1]) D3 = odlib.tri_product(rhoHat3, rhoHat1, R[2]) rho[1] *= (a[0] * D1 + a[1] * D2 + a[2] * D3) / (a[1] * D0) D1 = odlib.tri_product(rhoHat1, rhoHat2, R[0]) D2 = odlib.tri_product(rhoHat1, rhoHat2, R[1]) D3 = odlib.tri_product(rhoHat1, rhoHat2, R[2]) rho[2] *= (a[0] * D1 + a[1] * D2 + a[2] * D3) / (a[2] * D0) r = rho - R f1 = f(tauAt1, tauAt2, r[1], r2Dot) f3 = f(tauAt3, tauAt2, r[1], r2Dot) g1 = g(tauAt1, tauAt2, r[1], r2Dot) g3 = g(tauAt3, tauAt2, r[1], r2Dot) a[0] = g3 / (f1 * g3 - f3 * g1) a[2] = g1 / (f3 * g1 - f1 * g3) r[1] = a[0] * r[0] + a[2] * r[2] r2Dot = f3 / (g1 * f3 - g3 * f1) * r[0] + f1 / (g3 * f1 - g1 * f3) * r[2] iteration += 1 assert (iteration < maxIterations) # print(r) r[1] = odlib.rotateVector(r[1], 0, odlib.degreesToRadians(eclipticObliquity), 0) r2Dot = odlib.rotateVector(r2Dot, 0, odlib.degreesToRadians(eclipticObliquity), 0) elements = orbitalElements(r[1], r2Dot) elements[2] = odlib.radiansToDegrees(elements[2]) elements[3] = odlib.radiansToDegrees(elements[3]) elements[4] = odlib.radiansToDegrees(elements[4]) elements[5] = odlib.radiansToDegrees(elements[5]) while elements[4] < 0: elements[4] += 360 while elements[4] > 360: elements[4] -= 360 return elements
D1 = odlib.tri_product(rhoHat1, rhoHat2, R[0]) D2 = odlib.tri_product(rhoHat1, rhoHat2, R[1]) D3 = odlib.tri_product(rhoHat1, rhoHat2, R[2]) rho[2] *= (a[0] * D1 + a[1] * D2 + a[2] * D3) / (a[2] * D0) r = rho - R f1 = f(tauAt1, tauAt2, r[1], r2Dot) f3 = f(tauAt3, tauAt2, r[1], r2Dot) g1 = g(tauAt1, tauAt2, r[1], r2Dot) g3 = g(tauAt3, tauAt2, r[1], r2Dot) a[0] = g3 / (f1 * g3 - f3 * g1) a[2] = g1 / (f3 * g1 - f1 * g3) r[1] = a[0] * r[0] + a[2] * r[2] r2Dot = f3 / (g1 * f3 - g3 * f1) * r[0] + f1 / (g3 * f1 - g1 * f3) * r[2] iteration += 1 assert(iteration < maxIterations) r[1] = odlib.rotateVector(r[1], 0, odlib.degreesToRadians(23.4368815858), 0) r2Dot = odlib.rotateVector(r2Dot, 0, odlib.degreesToRadians(23.4368815858), 0) percentErrorR2 = abs(r[1] - realR2) / realR2 * 100 percentErrorR2Dot = abs(r2Dot - realR2Dot) / realR2Dot * 100 print('iterations', iteration) print(f"Expected r: {realR2}\nCalulated r: {r[1]}") print(f"Percent difference for each component: {percentErrorR2}\n") print(f"Expected rdot: {realR2Dot}\nCalulated rdot: {r2Dot}") print(f"Percent difference for each component: {percentErrorR2Dot}")
r = rho - R f1 = f(tauAt1, tauAt2, r[1], r2Dot) f3 = f(tauAt3, tauAt2, r[1], r2Dot) g1 = g(tauAt1, tauAt2, r[1], r2Dot) g3 = g(tauAt3, tauAt2, r[1], r2Dot) a[0] = g3 / (f1 * g3 - f3 * g1) a[2] = g1 / (f3 * g1 - f1 * g3) r[1] = a[0] * r[0] + a[2] * r[2] r2Dot = f3 / (g1 * f3 - g3 * f1) * r[0] + f1 / (g3 * f1 - g1 * f3) * r[2] iteration += 1 assert(iteration < maxIterations) print(r) r[1] = odlib.rotateVector(r[1], 0, odlib.degreesToRadians(eclipticObliquity), 0) r2Dot = odlib.rotateVector(r2Dot, 0, odlib.degreesToRadians(eclipticObliquity), 0) print('r and r2Dot',r[1], np.array(r2Dot) * odlib.k) elements = orbitalElements(r[1], r2Dot) elements[2] = odlib.radiansToDegrees(elements[2]) elements[3] = odlib.radiansToDegrees(elements[3]) elements[4] = odlib.radiansToDegrees(elements[4]) elements[5] = odlib.radiansToDegrees(elements[5]) while elements[4] < 0: elements[4] += 360 while elements[4] > 360: elements[4] -= 360 # Moves M to a negative angle to make the percent error more fitting