#!/usr/bin/env python import math import unittest import ephem class StarTests(unittest.TestCase): def test_Arcturus(self): s = ephem.star('Arcturus') s.compute(ephem.date('2017/1/1 12:00')) self.assertEqual(str(s.ra), '14:16:25.12') self.assertEqual(str(s.dec), '19:05:39.8') def test_Fomalhaut(self): s = ephem.star('Fomalhaut') self.assertEqual(s.name, 'Fomalhaut') self.assertRaises(RuntimeError, getattr, s, 'ra') def test_Fomalhaut_compute(self): s = ephem.star('Fomalhaut') s.compute() self.assertEqual(s.name, 'Fomalhaut') self.assertEqual(str(s._ra), '22:57:39.05') def test_Fomalhaut_autocompute(self): s = ephem.star('Fomalhaut', '1971/1/1') self.assertEqual(s.name, 'Fomalhaut') self.assertEqual(str(s._ra), '22:57:39.05') def test_catalog_size(self): # Prevent catalog from changing size accidentally during editing. self.assertEqual(len(ephem.stars.stars), 115) def test_unknown_star(self): self.assertRaises(KeyError, ephem.star, 'Alpha Centauri') class Test57NavigationStars(unittest.TestCase): """Tests all 57 common navigation stars against the Nautical Almanac for the date 2018-01-01 00:00:00. Reference data is from Her Majesty's Nautical Almanac Office Publication NP314-18 "The Nautical Almanac" (2017), ISBN 978-0-7077-41819. A secondary source, online, is: http://www.tecepe.com.br/scripts/AlmanacPagesISAPI.dll/pages?date=1%2F1%2F2018 """ NP314_DATE = '2018-01-01 00:00:00' # The resolution of NP314 is 0.1 minutes so we should only expect an error # of +/- 0.05 minutes. # In practice the errors exceed this so these tests are less # strict imposing an absolute error of +/- 0.3 minutes: # Tolerance Failures # +/- 0.3 minutes 0 # +/- 0.2 minutes 2 # +/- 0.1 minutes 6 # +/- 0.05 minutes 22 MAX_ERROR_DEGREES = 0.3 * 1.0 / 60 def _test_body(self, name, sha, dec, date=NP314_DATE): obj = ephem.star(name) obs = ephem.Observer() obs.date = date obj.compute(obs) exp_sha = ephem.degrees(sha.replace(' ', ':')) err_sha = math.degrees(2 * ephem.pi - obj.g_ra - exp_sha) self.assertTrue( abs(err_sha) < self.MAX_ERROR_DEGREES, 'SHA fail: {0!s:} !< {1!s:}' .format(abs(err_sha), self.MAX_ERROR_DEGREES) ) exp_dec = ephem.degrees(dec.replace(' ', ':')) err_dec = math.degrees(obj.g_dec - exp_dec) self.assertTrue( abs(err_dec) < self.MAX_ERROR_DEGREES, 'Dec. fail: {0!s:} !< {1!s:}' .format(abs(err_dec), self.MAX_ERROR_DEGREES) ) def test_Acamar(self): self._test_body('Acamar', '315 15.8', '-40 14.3') def test_Achernar(self): self._test_body('Achernar', '335 24.4', '-57 09.2') def test_Acrux(self): self._test_body('Acrux', '173 05.7', '-63 11.5') def test_Adhara(self): self._test_body('Adhara', '255 09.7', '-29 00.0') def test_Aldebaran(self): self._test_body('Aldebaran', '290 45.5', '16 32.5') def test_Alioth(self): self._test_body('Alioth', '166 18.1', '55 51.5') def test_Alkaid(self): self._test_body('Alkaid', '152 56.7', '49 13.3') def test_Alnair(self): self._test_body('Alnair', '27 40.3', '-46 52.6') def test_Alnilam(self): self._test_body('Alnilam', '275 42.9', '-1 11.7') def test_Alphard(self): self._test_body('Alphard', '217 52.8', '-8 44.3') def test_Alphecca(self): self._test_body('Alphecca', '126 8.7', '26 39.3') def test_Alpheratz(self): self._test_body('Alpheratz', '357 40.3', '29 11.4') def test_Altair(self): self._test_body('Altair', '62 5.6', '8 55.1') def test_Ankaa(self): self._test_body('Ankaa', '353 12.7', '-42 12.8') def test_Antares(self): self._test_body('Antares', '112 22.8', '-26 28.0') def test_Arcturus(self): self._test_body('Arcturus', '145 53.1', '19 5.4') def test_Atria(self): self._test_body('Atria', '107 22.3', '-69 3.2') def test_Avior(self): self._test_body('Avior', '234 16.1', '-59 34.0') def test_Bellatrix(self): self._test_body('Bellatrix', '278 28.4', '6 21.7') def test_Betelgeuse(self): self._test_body('Betelgeuse', '270 57.6', '7 24.4') def test_Canopus(self): self._test_body('Canopus', '263 54.2', '-52 42.5') def test_Capella(self): self._test_body('Capella', '280 29.3', '46 0.8') def test_Deneb(self): self._test_body('Deneb', '49 29.8', '45 20.9') def test_Denebola(self): self._test_body('Denebola', '182 30.5', '14 28.1') def test_Diphda(self): self._test_body('Diphda', '348 52.8', '-17 53.5') def test_Dubhe(self): self._test_body('Dubhe', '193 47.8', '61 39.0') def test_Elnath(self): self._test_body('Elnath', '278 8.4', '28 37.2') def test_Eltanin(self): self._test_body('Eltanin', '90 45.3', '51 29.3') def test_Enif(self): self._test_body('Enif', '33 44.3', '9 57.5') def test_Fomalhaut(self): self._test_body('Fomalhaut', '15 20.8', '-29 31.8') def test_Gacrux(self): self._test_body('Gacrux', '171 57.3', '-57 12.5') def test_Gienah(self): self._test_body('Gienah', '175 49.1', '-17 38.3') def test_Hadar(self): self._test_body('Hadar', '148 43.7', '-60 27.1') def test_Hamal(self): self._test_body('Hamal', '327 57.1', '23 32.8') def test_Kaus_Australis(self): self._test_body('Kaus Australis', '83 40.2', '-34 22.4') def test_Kochab(self): self._test_body('Kochab', '137 20.9', '74 4.8') def test_Markab(self): self._test_body('Markab', '13 35.4', '15 18.2') def test_Menkar(self): self._test_body('Menkar', '314 11.6', '4 9.4') def test_Menkent(self): self._test_body('Menkent', '148 4.1', '-36 27.2') def test_Miaplacidus(self): self._test_body('Miaplacidus', '221 38.1', '-69 47.3') def test_Mirfak(self): self._test_body('Mirfak', '308 35.5', '49 55.5') def test_Nunki(self): self._test_body('Nunki', '75 54.9', '-26 16.3') def test_Peacock(self): self._test_body('Peacock', '53 15.0', '-56 40.6') def test_Pollux(self): self._test_body('Pollux', '243 23.6', '27 58.7') def test_Procyon(self): self._test_body('Procyon', '244 56.2', '5 10.5') def test_Rasalhague(self): self._test_body('Rasalhague', '96 3.9', '12 33.0') def test_Regulus(self): self._test_body('Regulus', '207 40.0', '11 52.6') def test_Rigel(self): self._test_body('Rigel', '281 8.8', '-8 11.1') def test_Rigil_Kentaurus_2002(self): # The printed Nautical Almanac 2002, ISBN 0 11 887316 4 # For 2002-01-01 00:00:00 has the following values. self._test_body('Rigil Kentaurus', '140 4.6', '-60 50.2', '2002-01-01 00:00:00') def test_Rigil_Kentaurus_2017(self): # Her Majesty's Nautical Almanac Office Publication NP314-18 # "The Nautical Almanac" (2017). ISBN 978-0-7077-41819 # For 2018-01-01 00:00:00 has the following values. self._test_body('Rigil Kentaurus', '139 47.8', '-60 54.1', '2018-01-01 00:00:00') def test_Sabik(self): self._test_body('Sabik', '102 9.3', '-15 44.6') def test_Schedar(self): self._test_body('Schedar', '349 36.9', '56 38.3') def test_Shaula(self): self._test_body('Shaula', '96 18.1', '-37 6.7') def test_Sirius(self): self._test_body('Sirius', '258 30.7', '-16 44.7') def test_Spica(self): self._test_body('Spica', '158 28.1', '-11 15.1') def test_Suhail(self): self._test_body('Suhail', '222 49.8', '-43 30.3') def test_Vega(self): self._test_body('Vega', '80 37.3', '38 48.2') def test_Zubenelgenubi(self): self._test_body('Zubenelgenubi', '137 2.2', '-16 6.7') def test_number_tables_len(self): self.assertTrue(len(ephem.stars.STAR_NAME_NUMBER) == 57) self.assertTrue(len(ephem.stars.STAR_NUMBER_NAME) == 57) def test_number_tables_range(self): self.assertEqual(sorted(ephem.stars.STAR_NAME_NUMBER.values()), list(range(1, 58)) ) self.assertEqual(sorted(ephem.stars.STAR_NUMBER_NAME.keys()), list(range(1, 58)) ) def test_number_tables_cross_reference(self): for name, number in ephem.stars.STAR_NAME_NUMBER.items(): self.assertEqual(name, ephem.stars.STAR_NUMBER_NAME[number]) for number, name in ephem.stars.STAR_NUMBER_NAME.items(): self.assertEqual(number, ephem.stars.STAR_NAME_NUMBER[name])