def beginning_synodic_rotation(number): """This method calculates the epoch when the Carrington's synodic rotation No. 'number' starts. :param number: Number of Carrington's synodic rotation :type number: int :returns: Epoch when the provided rotation starts :rtype: :py:class:`Epoch` :raises: TypeError if input value is of wrong type. >>> epoch = Sun.beginning_synodic_rotation(1699) >>> print(round(epoch(), 3)) 2444480.723 """ # First check that input values are of correct types if not isinstance(number, int): raise TypeError("Invalid input type") # Apply formula (29.1) jde = 2398140.227 + 27.2752316 * number # Now, find the correction using formula (29.2) m = 281.96 + 26.882476 * number m = Angle(m) m = m.rad() delta = 0.1454 * sin(m) - 0.0085 * sin(2.0 * m) - 0.0141 * cos(2.0 * m) # Apply the correction jde += delta return Epoch(jde)
def test_coordinates_times_rise_transit_set(): """Tests the times_rise_transit_set() method of Coordinates module""" longitude = Angle(71, 5, 0.0) latitude = Angle(42, 20, 0.0) alpha1 = Angle(2, 42, 43.25, ra=True) delta1 = Angle(18, 2, 51.4) alpha2 = Angle(2, 46, 55.51, ra=True) delta2 = Angle(18, 26, 27.3) alpha3 = Angle(2, 51, 7.69, ra=True) delta3 = Angle(18, 49, 38.7) h0 = Angle(-0.5667) delta_t = 56.0 theta0 = Angle(11, 50, 58.1, ra=True) rising, transit, setting = times_rise_transit_set(longitude, latitude, alpha1, delta1, alpha2, delta2, alpha3, delta3, h0, delta_t, theta0) assert abs(round(rising, 4) - 12.4238) < TOL, \ "ERROR: 1st times_rise_transit_set() test, 'rising' time doesn't match" assert abs(round(transit, 3) - 19.675) < TOL, \ "ERROR: 2nd times_rise_transit_set() test, 'transit' doesn't match" assert abs(round(setting, 3) - 2.911) < TOL, \ "ERROR: 3rd times_rise_transit_set() test, 'setting' doesn't match"
def apparent_longitude_coarse(epoch): """This method provides the Sun's apparent longitude with a relatively low accuracy of about 0.01 degree. :param epoch: Epoch to compute the position of the Sun :type epoch: :py:class:`Epoch` :returns: A tuple containing the sun_apparent (ecliptical) longitude (as an Angle object) and the radius vector in astronomical units. :rtype: tuple :raises: TypeError if input value is of wrong type. >>> epoch = Epoch(1992, 10, 13) >>> app_lon, r = Sun.apparent_longitude_coarse(epoch) >>> print(app_lon.dms_str(n_dec=0)) 199d 54' 32.0'' >>> print(round(r, 5)) 0.99766 """ # First check that input values are of correct types if not isinstance(epoch, Epoch): raise TypeError("Invalid input type") # First find the true longitude sun = Sun() true_lon, r = sun.true_longitude_coarse(epoch) # Compute the time in Julian centuries t = (epoch - JDE2000) / 36525.0 # Then correct for nutation and aberration omega = 125.04 - 1934.136 * t omega = Angle(omega) lambd = true_lon - 0.00569 - 0.00478 * sin(omega.rad()) return (lambd, r)
def test_coordinates_motion_in_space(): """Tests the motion_in_space() method of Coordinates module""" ra = Angle(6, 45, 8.871, ra=True) dec = Angle(-16.716108) pm_ra = Angle(0, 0, -0.03847, ra=True) pm_dec = Angle(0, 0, -1.2053) dist = 2.64 vel = -7.6 alpha, delta = motion_in_space(ra, dec, dist, vel, pm_ra, pm_dec, -2000.0) assert alpha.ra_str(False, 2) == "6:46:25.09", \ "ERROR: 1st motion_in_space() test, 'right ascension' doesn't match" assert delta.dms_str(False, 1) == "-16:3:0.8", \ "ERROR: 2nd motion_in_space() test, 'declination' doesn't match" alpha, delta = motion_in_space(ra, dec, dist, vel, pm_ra, pm_dec, -3000.0) assert alpha.ra_str(False, 2) == "6:47:2.67", \ "ERROR: 3rd motion_in_space() test, 'right ascension' doesn't match" assert delta.dms_str(False, 1) == "-15:43:12.3", \ "ERROR: 4th motion_in_space() test, 'declination' doesn't match" alpha, delta = motion_in_space(ra, dec, dist, vel, pm_ra, pm_dec, -12000.0) assert alpha.ra_str(False, 2) == "6:52:25.72", \ "ERROR: 5th motion_in_space() test, 'right ascension' doesn't match" assert delta.dms_str(False, 1) == "-12:50:6.7", \ "ERROR: 6th motion_in_space() test, 'declination' doesn't match"
def gregorian_day_of_nawruz(year): if year == 2059: return 20 # get time of spring equinox equinox = Sun.get_equinox_solstice(year, "spring") # get sunset times in Tehran latitude = Angle(35.6944) longitude = Angle(51.4215) # get time of sunset in Tehran days = [19, 20, 21] sunsets = list( map(lambda x: Epoch(year, 3, x).rise_set(latitude, longitude)[1], days)) # compare if equinox < sunsets[1]: if equinox < sunsets[0]: return 19 else: return 20 else: if equinox < sunsets[2]: return 21 else: return 22
def test_interpolation_call(): """Tests the __call__() method of Interpolation class""" m = Interpolation([-1.0, 0.0, 1.0], [-2.0, 3.0, 2.0]) assert abs(m(-0.8) - (-0.52)) < TOL, \ "ERROR: In 1st __call__() test, output value doesn't match" assert abs(m(0.7) - 2.93) < TOL, \ "ERROR: In 2nd __call__() test, output value doesn't match" assert abs(m(-1.0) - (-2.0)) < TOL, \ "ERROR: In 3rd __call__() test, output value doesn't match" m = Interpolation([-3.0, 0.0, 2.5], [12.0, -3.0, -1.75]) assert abs(m(-2.0) - 5.0) < TOL, \ "ERROR: In 4th __call__() test, output value doesn't match" assert abs(m(2.5) - (-1.75)) < TOL, \ "ERROR: In 5th __call__() test, output value doesn't match" # This interpolation test uses Right Ascension a = Angle(i_ra(11.0)) h, m, s, sign = a.ra_tuple() assert abs(h - 10.0) < TOL and \ abs(m - 25.0) < TOL and \ abs(s - 40.0014375) < TOL and \ abs(sign == 1.0), \ "ERROR: In 6th __call__() test, output value doesn't match" # Test with 6 interpolation table entries, based on sine function assert abs(i_sine(30.0) - 0.5) < TOL, \ "ERROR: In 7th __call__() test, output value doesn't match"
def main(): # Let's define a small helper function def print_me(msg, val): print("{}: {}".format(msg, val)) # Let's show some uses of Minor class print("\n" + 35 * "*") print("*** Use of Minor class") print(35 * "*" + "\n") # Let's compute the equatorial coordinates of comet Encke a = 2.2091404 e = 0.8502196 q = a * (1.0 - e) i = Angle(11.94524) omega = Angle(334.75006) w = Angle(186.23352) t = Epoch(1990, 10, 28.54502) epoch = Epoch(1990, 10, 6.0) minor = Minor(q, e, i, omega, w, t) ra, dec, elong = minor.geocentric_position(epoch) print_me("Right ascension", ra.ra_str(n_dec=1)) # 10h 34' 13.7'' print_me("Declination", dec.dms_str(n_dec=0)) # 19d 9' 32.0'' print_me("Elongation", round(elong, 2)) # 40.51 print("") # Now compute the heliocentric ecliptical coordinates lon, lat = minor.heliocentric_ecliptical_position(epoch) print_me("Heliocentric ecliptical longitude", lon.dms_str(n_dec=1)) # 66d 51' 57.8'' print_me("Heliocentric ecliptical latitude", lat.dms_str(n_dec=1))
def geometric_heliocentric_position(epoch): """This method computes the geometric heliocentric position of planet Pluto for a given epoch. :param epoch: Epoch to compute Pluto position, as an Epoch object :type epoch: :py:class:`Epoch` :returns: A tuple with the heliocentric longitude and latitude (as :py:class:`Angle` objects), and the radius vector (as a float, in astronomical units), in that order :rtype: tuple :raises: TypeError if input value is of wrong type. :raises: ValueError if input epoch outside the 1885-2099 range. >>> epoch = Epoch(1992, 10, 13.0) >>> l, b, r = Pluto.geometric_heliocentric_position(epoch) >>> print(round(l, 5)) 232.74071 >>> print(round(b, 5)) 14.58782 >>> print(round(r, 6)) 29.711111 """ # First check that input value is of correct types if not isinstance(epoch, Epoch): raise TypeError("Invalid input type") # Check that the input epoch is within valid range y = epoch.year() if y < 1885.0 or y > 2099.0: raise ValueError("Epoch outside the 1885-2099 range") t = (epoch - JDE2000) / 36525.0 jj = 34.35 + 3034.9057 * t ss = 50.08 + 1222.1138 * t pp = 238.96 + 144.96 * t # Compute the arguments corr_lon = 0.0 corr_lat = 0.0 corr_rad = 0.0 for n in range(len(PLUTO_ARGUMENT)): iii, jjj, kkk = PLUTO_ARGUMENT[n] alpha = Angle(iii * jj + jjj * ss + kkk * pp).to_positive() alpha = alpha.rad() sin_a = sin(alpha) cos_a = cos(alpha) a_lon, b_lon = PLUTO_LONGITUDE[n] corr_lon += a_lon * sin_a + b_lon * cos_a a_lat, b_lat = PLUTO_LATITUDE[n] corr_lat += a_lat * sin_a + b_lat * cos_a a_rad, b_rad = PLUTO_RADIUS_VECTOR[n] corr_rad += a_rad * sin_a + b_rad * cos_a # The coefficients in the tables were scaled up. Let's scale them down corr_lon /= 1000000.0 corr_lat /= 1000000.0 corr_rad /= 10000000.0 lon = Angle(238.958116 + 144.96 * t + corr_lon) lat = Angle(-3.908239 + corr_lat) radius = 40.7241346 + corr_rad return lon, lat, radius
def test_angle_set_radians(): """Tests the set_radians() method of Angle class""" a = Angle() a.set_radians(pi) # Input is in radians assert abs(a() - 180.0) < TOL, \ "ERROR: 1st set_radians() test, degrees value doesn't match"
def test_coordinates_diurnal_path_horizon(): """Tests the diurnal_path_horizon() method of Coordinates module""" dec = Angle(23.44) lat = Angle(40.0) j = diurnal_path_horizon(dec, lat) assert j.dms_str(n_dec=1) == "45d 31' 28.4''", \ "ERROR: 1st diurnal_path_horizon() test, 'j' angle doesn't match"
def test_angle_reduce_deg(): """Tests reduce_deg() static method of Angle class""" d = Angle.reduce_deg(745.67) assert abs(d - 25.67) < TOL, \ "ERROR: In 1st reduce_deg() test, degrees value doesn't match" d = Angle.reduce_deg(-360.86) assert abs(d - (-0.86)) < TOL, \ "ERROR: In 2nd reduce_deg() test, degrees value doesn't match"
def test_coordinates_parallactic_angle(): """Tests the parallactic_angle() method of Coordinates module""" hour_angle = Angle(0.0) declination = Angle(45.0) latitude = Angle(50.0) q = parallactic_angle(hour_angle, declination, latitude) assert q.dms_str(n_dec=1) == "0d 0' 0.0''", \ "ERROR: 1st parallactic_angle() test, 'lon1' doesn't match"
def test_coordinates_ecliptic_equator(): """Tests the ecliptic_equator() method of Coordinates module""" lon = Angle(0.0) lat = Angle(0.0) eps = Angle(23.5) ang_ecl_equ = ecliptic_equator(lon, lat, eps) assert ang_ecl_equ.dms_str(n_dec=1) == "156d 30' 0.0''", \ "ERROR: 1st ecliptic_equator() test, 'ang_ecl_equ' doesn't match"
def test_angle_dms_str(): """Tests dms_str() method of Angle class""" a = Angle(0, -46.25, 0.0) result = a.dms_str() assert result == "-46' 15.0''", \ "ERROR: In 1st dms_str() test, the output value doesn't match" result = a.dms_str(False) assert result == "0:-46:15.0", \ "ERROR: In 2nd dms_str() test, the output value doesn't match"
def test_magnitude(): """Tests the magnitude() method of Saturn class""" sun_dist = 9.867882 earth_dist = 10.464606 delta_u = Angle(16.442) b = Angle(4.198) m = Saturn.magnitude(sun_dist, earth_dist, delta_u, b) assert abs(m - 1.9) < TOL, \ "ERROR: 1st magnitude() test doesn't match"
def test_angle_ra_str(): """Tests ra_str() method of Angle class""" a = Angle(138.75) result = a.ra_str() assert result == "9h 15' 0.0''", \ "ERROR: In 1st ra_str() test, the output value doesn't match" result = a.ra_str(False) assert result == "9:15:0.0", \ "ERROR: In 2nd ra_str() test, the output value doesn't match"
def test_coordinates_angular_separation(): """Tests the angular_separation() method of Coordinates module""" alpha1 = Angle(14, 15, 39.7, ra=True) delta1 = Angle(19, 10, 57.0) alpha2 = Angle(13, 25, 11.6, ra=True) delta2 = Angle(-11, 9, 41.0) sep_ang = angular_separation(alpha1, delta1, alpha2, delta2) assert abs(round(sep_ang, 3) - 32.793) < TOL, \ "ERROR: 1st angular_separation() test, 'sep_ang' value doesn't match"
def test_angle_str(): """Tests the __str__() method of Angle class""" type_ok = False a = Angle(40, -46.5, 0.0) if isinstance(a.__str__(), str): # Test the returned type type_ok = True assert type_ok, "ERROR: In 1st __str__() test, type doesn't match" assert a.__str__() == "-40.775", \ "ERROR: In 2nd __str__() test, degrees value doesn't match"
def test_coordinates_galactic2equatorial(): """Tests the galactic2equatorial() method of Coordinates module""" lon = Angle(12.9593) lat = Angle(6.0463) ra, dec = galactic2equatorial(lon, lat) assert ra.ra_str(n_dec=1) == "17h 48' 59.7''", \ "ERROR: 1st galactic2equatorial() test, 'ra' doesn't match" assert dec.dms_str(n_dec=0) == "-14d 43' 8.0''", \ "ERROR: 2nd galactic2equatorial() test, 'declination' doesn't match"
def test_coordinates_equatorial2galactic(): """Tests the equatorial2galactic() method of Coordinates module""" ra = Angle(17, 48, 59.74, ra=True) dec = Angle(-14, 43, 8.2) lon, lat = equatorial2galactic(ra, dec) assert abs(round(lon, 4) - 12.9593) < TOL, \ "ERROR: 1st equatorial2galactic() test, 'longitude' doesn't match" assert abs(round(lat, 4) - 6.0463) < TOL, \ "ERROR: 2nd equatorial2galactic() test, 'latitude' doesn't match"
def test_coordinates_horizontal2equatorial(): """Tests the horizontal2equatorial() method of Coordinates module""" azi = Angle(68.0337) ele = Angle(15.1249) lat = Angle(38, 55, 17) h, dec = horizontal2equatorial(azi, ele, lat) assert abs(round(h, 4) - 64.3521) < TOL, \ "ERROR: 1st horizontal2equatorial() test, 'hour angle' doesn't match" assert dec.dms_str(n_dec=0) == "-6d 43' 12.0''", \ "ERROR: 2nd horizontal2equatorial() test, 'declination' match"
def test_coordinates_ecliptical2equatorial(): """Tests the ecliptical2equatorial() method of Coordinates module""" lon = Angle(113.21563) lat = Angle(6.68417) epsilon = Angle(23.4392911) ra, dec = ecliptical2equatorial(lon, lat, epsilon) assert ra.ra_str(n_dec=3) == "7h 45' 18.946''", \ "ERROR: 1st ecliptical2equatorial() test, 'ra' doesn't match" assert dec.dms_str(n_dec=2) == "28d 1' 34.26''", \ "ERROR: 2nd ecliptical2equatorial() test, 'declination' doesn't match"
def test_coordinates_equatorial2ecliptical(): """Tests the equatorial2ecliptical() method of Coordinates module""" ra = Angle(7, 45, 18.946, ra=True) dec = Angle(28, 1, 34.26) epsilon = Angle(23.4392911) lon, lat = equatorial2ecliptical(ra, dec, epsilon) assert abs(round(lon(), 5) - 113.21563) < TOL, \ "ERROR: 1st equatorial2ecliptical() test, 'longitude' doesn't match" assert abs(round(lat(), 5) - 6.68417) < TOL, \ "ERROR: 2nd equatorial2ecliptical() test, 'latitude' doesn't match"
def test_angle_ipow(): """Tests the accumulative power operation in Angles""" a = Angle(13, 30) a **= 3 assert abs(a() - 300.375) < TOL, \ "ERROR: In 1st __ipow__() test, degrees value doesn't match" b = Angle(-2.0) a **= b assert abs(a() - 1.108338532999e-05) < TOL, \ "ERROR: In 2nd __ipow__() test, degrees value doesn't match"
def test_angle_mod(): """Tests the module of Angles""" a = Angle(152.7) b = a % 50 assert abs(b() - 2.7) < TOL, \ "ERROR: In 1st __mod__() test, degrees value doesn't match" a = Angle(-13, 30) b = a % 7 assert abs(b() - (-6.5)) < TOL, \ "ERROR: In 2nd __mod__() test, degrees value doesn't match"
def test_angle_abs(): """Tests the absolute value of Angles""" a = Angle(152.7) b = abs(a) assert abs(b() - 152.7) < TOL, \ "ERROR: In 1st __abs__() test, degrees value doesn't match" a = Angle(-13, 30) b = abs(a) assert abs(b() - 13.5) < TOL, \ "ERROR: In 2nd __abs__() test, degrees value doesn't match"
def test_angle_imod(): """Tests the accumulative module between Angles""" a = Angle(152.7) a %= 50 assert abs(a() - 2.7) < TOL, \ "ERROR: In 1st __imod__() test, degrees value doesn't match" a = Angle(-13, 30) a %= 7 assert abs(a() - (-6.5)) < TOL, \ "ERROR: In 2nd __imod__() test, degrees value doesn't match"
def test_coordinates_apparent_position(): """Tests the apparent_position() method of Coordinates module""" epoch = Epoch(2028, 11, 13.19) alpha = Angle(2, 46, 11.331, ra=True) delta = Angle(49, 20, 54.54) sun_lon = Angle(231.328) app_alpha, app_delta = apparent_position(epoch, alpha, delta, sun_lon) assert app_alpha.ra_str(n_dec=2) == "2h 46' 14.39''", \ "ERROR: 1st apparent_position() test, 'app_alpha' value doesn't match" assert app_delta.dms_str(n_dec=2) == "49d 21' 7.45''", \ "ERROR: 2nd apparent_position() test, 'app_delta' value doesn't match"
def test_angle_neg(): """Tests the negation of Angles""" a = Angle(152.7) b = -a assert abs(b() - (-152.7)) < TOL, \ "ERROR: In 1st __neg__() test, degrees value doesn't match" a = Angle(-13, 30) b = -a assert abs(b() - 13.5) < TOL, \ "ERROR: In 2nd __neg__() test, degrees value doesn't match"
def test_angle_le(): """Tests the 'is less or equal' operator of Angles""" # NOTE: Test of 'is less or equal' also test 'is greater than' operator a = Angle(152.7) b = Angle(152.70000001) assert (a <= b), \ "ERROR: In 1st __le__() test, Angles values don't match operator" a = Angle(-13, 30) b = Angle(-13.5) assert (a <= b), \ "ERROR: In 2nd __le__() test, Angles values don't match operator"