def equinox_solstice_iterative(year_, idx_, prec_): jde_0 = mean_equinox_solstice(year_, idx_) jdn_to_ret = JulianDayNumber(Date(year_, 1, 1), Time(0, 0, 0)) jdn_to_ret.jdn = jde_0 # Hack while True: sun = Sun(jdn_to_ret) dpsi = Ecliptic(jdn_to_ret).get_dpsi_low().rads fk5_correction = -radians(0.09033 / 3600.0) aberration = -radians(20.4898 / 3600.0 / sun.R) lambda_app = sun.L + dpsi + fk5_correction + aberration dday = 58 * sin(idx_ * pi / 2 - lambda_app) if fabs(dday) <= fabs(prec_): break jdn_to_ret.jdn += dday return jdn_to_ret
def equinox_solstice_helper(year_, idx_): jde_0 = mean_equinox_solstice(year_, idx_) T = (jde_0 - epoch_j2000.jdn) / julian_century W = radians(35999.373 * T - 2.47) dlambda = 1 + 0.0334 * cos(W) + 0.0007 * cos(2 * W) S = 0.0 for (A, B, C) in table27c: S += A * cos(radians(B + C * T)) jde = jde_0 + (0.00001 * S) / dlambda jdn_to_return = JulianDayNumber(Date(year_, 1, 1), Time(0, 0, 0)) jdn_to_return.jdn = jde # Roundabout way of creating a JDN return jdn_to_return
def conjunction(dates_, coords1_, coords2_, prec_): assert isinstance(dates_, list) and isinstance(coords1_, list) \ and isinstance (coords2_, list), 'Arguments must be lists' assert len(dates_) == 5 and len(coords1_) == 5 and len(coords2_) == 5, \ 'Argument list must contain exactly 5 elements' for date in dates_: assert isinstance(date, JulianDayNumber), \ 'dates_ must contain only JulianDayNumber objects' check_sphcoords(coords1_) check_sphcoords(coords2_) # Construct a list of 'decimal' dates jdndates = [] for date in dates_: jdndates.append(date.jdn) print # Construct a list of differences in radians for alpha and delta between # object1 and object 2 for the dates given dalphas = [] ddeltas = [] for coord1, coord2 in zip(coords1_, coords2_): dalpha = coord1.a.rads - coord2.a.rads dalphas.append(dalpha) ddelta = coord1.b.rads - coord2.b.rads ddeltas.append(ddelta) # Interpolate to find the zero for dalphas dalpha_data = zip(jdndates, dalphas) ipol = Inter5polate(dalpha_data) jdndate_conjunction = ipol.zero(prec_) # Interpolate to find the value of ddelta for the date of conjunction ddelta_data = zip(jdndates, ddeltas) ipol = Inter5polate(ddelta_data) ddelta_conjunction_rads = ipol.compute(jdndate_conjunction) # Create objects to return date_return = JulianDayNumber(Date(0, 1, 1), Time(0, 0, 0)) date_return.jdn = jdndate_conjunction # Hack to build a JDN from a decimal value ddelta_return = Latitude(ddelta_conjunction_rads) return (date_return, ddelta_return)
return equinox_solstice_helper(year_, 1) def autumn_equinox(year_): """ Julian Day Number of the Autumn Equinox in the given year""" return equinox_solstice_helper(year_, 2) def winter_solstice(year_): """ Julian Day Number of the Winter Solstice in the given year""" return equinox_solstice_helper(year_, 3) if __name__ == "__main__": # Sun tests sooraj = Sun(JulianDayNumber(Date(1992, 10, 13), Time(0, 0, 0))) print sooraj.get_ecliptical() # 199deg54'36", 0 print sooraj.get_ecliptical_apparent() # 199deg54'32", 0 print sooraj.get_equatorial() print sooraj.get_equatorial_apparent() # 13h13m31.4s, -7deg47'06" print sooraj.get_rectangular() print # Equinox/Solstice tests years = [1962, 1975, 1979, 2013, 2017, 2018, 2019, 2020] prec = 1e-6 for year in years: print 'Year', year instant = spring_equinox(year) print 'Spring Equinox :', instant.get_date(), instant.get_time() instant = summer_solstice(year)
def apply_correction(self, coord): assert isinstance(coord, Equatorial), 'coord must be a Equatorial' alpha = coord.a.rads + self.zeta delta0 = coord.b.rads A = cos(delta0)*sin(alpha) B = cos(self.theta)*cos(delta0)*cos(alpha) - sin(self.theta)*sin(delta0) C = sin(self.theta)*cos(delta0)*cos(alpha) + cos(self.theta)*sin(delta0) alpha = self.zappa + atan2(A,B) # If the object is close to the celestial pole if fabs(delta0 - pi/2) < radians(0.5): delta = acos(sqrt(A**2+B**2)) else: delta = asin(C) return Equatorial(Longitude(alpha), Latitude(delta)) if __name__ == "__main__": epoch_start = epoch_j2000 epoch_end = JulianDayNumber(Date(2028,11,13),Time(4,28,0)) prec = Precession(epoch_start, epoch_end) # theta Persei (proper motion corrected) theta_persei_epoch_start = Equatorial( Longitude(radians(41.054063)), Latitude(radians(49.227750)) ) print prec.apply_correction(theta_persei_epoch_start) # 2h46m11.331s, +49deg20'54.54"
""" def conjunction_with_star(dates_, star_, coords_, prec_): assert isinstance(star_, SphCoord), 'star_ must be a SphCoord object' # We assume the star's coordinates stay constant over the list of dates_ # provided. Create a dummy list of coords corresponding to the dates_ # Use copies of the original star_ to avoid accidental pitfalls with # repeated references star_coords = [copy.copy(star_) for date in dates] return conjunction(dates_, star_coords, coords_, prec_) if __name__ == "__main__": dates = [ JulianDayNumber(Date(1991, 8, 5), Time(0, 0, 0)), JulianDayNumber(Date(1991, 8, 6), Time(0, 0, 0)), JulianDayNumber(Date(1991, 8, 7), Time(0, 0, 0)), JulianDayNumber(Date(1991, 8, 8), Time(0, 0, 0)), JulianDayNumber(Date(1991, 8, 9), Time(0, 0, 0)), ] # Mercury coords1 = [ SphCoord( Longitude(radians((10.0 + 24.0 / 60.0 + 30.125 / 3600.0) * 15)), Latitude(radians(6 + 26.0 / 60.0 + 32.05 / 3600.0))), SphCoord( Longitude(radians((10.0 + 25.0 / 60.0 + 0.342 / 3600.0) * 15)), Latitude(radians(6 + 10.0 / 60.0 + 57.72 / 3600.0))), SphCoord( Longitude(radians((10.0 + 25.0 / 60.0 + 12.515 / 3600.0) * 15)),
# Obliquity NOT corrected for nutation ######## def get_obliquity_uncorrected(self): """Obliquity NOT corrected for nutation as an Angle object""" return Angle(self.epsilon_0) ######## # Obliquity corrected for nutation ######## def get_obliquity_corrected(self): """Obliquity corrected for nutation as an Angle object""" # @todo Use the more accurate value for d_epsilon return Angle(self.epsilon_0 + self.d_epsilon_low) if __name__ == "__main__": jdn = JulianDayNumber(Date(1987, 4, 10), Time(0, 0, 0)) ecliptic = Ecliptic(jdn) print ecliptic.get_dpsi_low() # -3.9" print ecliptic.get_depsilon_low() # +9.4" print ecliptic.get_obliquity_uncorrected() # 23deg 26'27.407" print ecliptic.get_obliquity_corrected() # 23def 26'36.850" print ecliptic_j2k = Ecliptic(epoch_j2000) print 'Ecliptic J2000:', ecliptic_j2k.get_obliquity_uncorrected( ) # 23deg26'21.448" print 'Ecliptic J2000 (corrected):', ecliptic_j2k.get_obliquity_corrected( ) # 23deg 26'15.69"
from math import radians from angle import Angle from calendar import Date, Time, JulianDayNumber julian_year = 365.25 julian_century = 36525.0 julian_millennia = julian_century * 10 epoch_j2000 = JulianDayNumber(Date(2000, 1, 1), Time(12, 0, 0)) # 2451545.0 TD # Obliquity of the Ecliptic referred to J2000 # To use with apparent RA and declination, use epsilon_j2000_corrected which # includes nutation epsilon_j2000 = Angle(radians(23 + (26 + 21.448 / 60.0) / 60.0)) epsilon_j2000_corrected = Angle(radians(23 + (26 + 15.69 / 60.0) / 60.0)) if __name__ == "__main__": print 'J2000:', epoch_j2000 print 'epsilon:', epsilon_j2000 print 'epsilon (corrected):', epsilon_j2000_corrected
assert isinstance(jdnumber, JulianDayNumber), 'Invalid Julian Day Number' # Number of Julian centuries since J2000 T = (jdnumber.jdn - epoch_j2000.jdn) / julian_century ret_deg = 280.46061837 \ + 360.98564736629*(jdnumber.jdn - epoch_j2000.jdn) \ + (0.000387933 - T/38710000.0)*T*T return Longitude(radians(ret_deg)) """ Apparent Sidereal Time at Greenwich for a given UT @return Greenwich AST as a Longitude object """ def AST(jdnumber): assert isinstance(jdnumber, JulianDayNumber), 'Invalid Julian Day Number' mst = MST(jdnumber) raise RuntimeError('@todo AST needs correction for nutation') if __name__ == "__main__": jdn = JulianDayNumber(Date(2017, 9, 15), Time(22, 20, 11)) theta_angle = MST(jdn) print theta_angle print MST(JulianDayNumber(Date(1987, 4, 10), Time(19, 21, 0))).hms() try: AST(jdn) except RuntimeError as e: print 'Error:', e
# Sirius coord_0 = Equatorial(Longitude(radians(101.286962)), Latitude(radians(-16.716108))) annual_pm = (Angle(-radians(0.03847 / 3600.0 * 15.0)), Angle(-radians(1.2053 / 3600.0))) epoch_0 = 2000.0 epoch_targets = [1000.0, 0.0, -1000.0, -2000.0, -10000.0] for epoch in epoch_targets: epoch_yrs = epoch - epoch_0 print proper_motion(coord_0, 2.64, -7.6 / 977792.0, annual_pm, epoch_yrs) print # theta Persei at epoch J2000 epoch_start = epoch_j2000 epoch_target = JulianDayNumber(Date(2028, 11, 13), Time(4, 28, 0)) # 2028 Nov 13.19 TD theta_persei_epoch_start = Equatorial( Longitude(radians((2.0 + 44.0 / 60.0 + 11.986 / 3600.0) * 15)), Latitude(radians(49.0 + 13.0 / 60.0 + 42.48 / 3600.0))) annual_pm = (Angle(radians(0.03425 / 3600.0 * 15)), Angle(-radians(0.0895 / 3600.0))) epoch_yrs = (epoch_target.jdn - epoch_start.jdn) / julian_year theta_persei_epoch_start_pm_corrected = \ proper_motion_classical(theta_persei_epoch_start, annual_pm, epoch_yrs) print theta_persei_epoch_start_pm_corrected # 2h44m12.975s, +49deg 13'39.90" print # Precession test prec = Precession(epoch_start, epoch_target) theta_persei_epoch_target = \