def testRADec(self): # We won't compare Vmag, because this also needs information on trailing losses. times = self.jpl['mjdUTC'].unique() deltaRA = np.zeros(len(times), float) deltaDec = np.zeros(len(times), float) for i, t in enumerate(times): # Find the JPL objIds visible at this time. j = self.jpl.query('mjdUTC == @t').sort_values('objId') # Set the ephems, using the objects seen at this time. suborbits = self.orbits.orbits.query( 'objId in @j.objId').sort_values('objId') subOrbits = Orbits() subOrbits.setOrbits(suborbits) ephems = PyOrbEphemerides() ephems.setOrbits(subOrbits) ephs = ephems.generateEphemerides([t], timeScale='UTC', obscode=807, ephMode='N', ephType='Basic', byObject=False) deltaRA[i] = np.abs(ephs['ra'] - j['ra_deg'].values).max() deltaDec[i] = np.abs(ephs['dec'] - j['dec_deg'].values).max() # Convert to mas deltaRA *= 3600. * 1000. deltaDec *= 3600. * 1000. # Much of the time we're closer than 1mas, but there are a few which hit higher values. print('max JPL errors', np.max(deltaRA), np.max(deltaDec)) print('std JPL errors', np.std(deltaRA), np.std(deltaDec)) self.assertLess(np.max(deltaRA), 25) self.assertLess(np.max(deltaDec), 25) self.assertLess(np.std(deltaRA), 3) self.assertLess(np.std(deltaDec), 3)
def testRADec(self): # We won't compare Vmag, because this also needs information on trailing losses. times = self.jpl['mjdUTC'].unique() deltaRA = np.zeros(len(times), float) deltaDec = np.zeros(len(times), float) for i, t in enumerate(times): # Find the JPL objIds visible at this time. j = self.jpl.query('mjdUTC == @t').sort_values('objId') # Set the ephems, using the objects seen at this time. suborbits = self.orbits.orbits.query('objId in @j.objId').sort_values('objId') subOrbits = Orbits() subOrbits.setOrbits(suborbits) ephems = PyOrbEphemerides() ephems.setOrbits(subOrbits) ephs = ephems.generateEphemerides([t], timeScale='UTC', obscode=807, byObject=False) deltaRA[i] = np.abs(ephs['ra'] - j['ra_deg'].as_matrix()).max() deltaDec[i] = np.abs(ephs['dec'] - j['dec_deg'].as_matrix()).max() # Convert to mas deltaRA *= 3600. * 1000. deltaDec *= 3600. * 1000. # Much of the time we're closer than 1mas, but there are a few which hit higher values. self.assertTrue(np.max(deltaRA) < 18) self.assertTrue(np.max(deltaDec) < 6) self.assertTrue(np.std(deltaRA) < 2) self.assertTrue(np.std(deltaDec) < 1) print('max JPL errors', np.max(deltaRA), np.max(deltaDec)) print('std JPL errors', np.std(deltaRA), np.std(deltaDec))
class TestChebyValues(unittest.TestCase): def setUp(self): self.testdatadir = 'orbits_testdata' self.coeffFile = 'test_coeffs' self.residFile = 'test_resids' self.failedFile = 'test_failed' self.orbits = Orbits() self.orbits.readOrbits(os.path.join(self.testdatadir, 'test_orbitsNEO.s3m'), skiprows=1) self.pyephems = PyOrbEphemerides(os.path.join(os.getenv('OORB_DATA'), 'DE405.dat')) self.pyephems.setOrbits(self.orbits) self.tStart = self.orbits.orbits.epoch.iloc[0] self.interval = 15 self.nCoeffs = 14 self.chebyFits = ChebyFits(self.orbits, self.tStart, self.tStart+self.interval, ngran=64, skyTolerance=2.5, nDecimal=2, nCoeff_position=self.nCoeffs, obscode=807) self.setLength = 0.5 self.chebyFits.calcSegmentLength(length=self.setLength) self.chebyFits.calcSegments() self.chebyFits.write(self.coeffFile, self.residFile, self.failedFile, append=False) self.coeffKeys = ['objId', 'tStart', 'tEnd', 'ra', 'dec', 'delta', 'vmag', 'elongation'] def tearDown(self): del self.orbits del self.chebyFits os.remove(self.coeffFile) os.remove(self.residFile) if os.path.isfile(self.failedFile): os.remove(self.failedFile) def testSetCoeff(self): # Test setting coefficients directly from chebyFits outputs. chebyValues = ChebyValues() chebyValues.setCoefficients(self.chebyFits) for k in self.coeffKeys: self.assertTrue(k in chebyValues.coeffs) self.assertTrue(isinstance(chebyValues.coeffs[k], np.ndarray)) self.assertEqual(len(np.unique(chebyValues.coeffs['objId'])), len(self.orbits)) # This will only be true for carefully selected length/orbit type, where subdivision did not occur. # For the test MBAs, a len=1day will work. For the test NEOs, a len=0.25 day will work (with 2.5mas skyTol). #self.assertEqual(len(chebyValues.coeffs['tStart']), (self.interval / self.setLength) * len(self.orbits)) self.assertEqual(len(chebyValues.coeffs['ra'][0]), self.nCoeffs) self.assertTrue('meanRA' in chebyValues.coeffs) self.assertTrue('meanDec' in chebyValues.coeffs) def testReadCoeffs(self): # Test reading the coefficients from disk. chebyValues = ChebyValues() chebyValues.readCoefficients(self.coeffFile) chebyValues2 = ChebyValues() chebyValues2.setCoefficients(self.chebyFits) for k in chebyValues.coeffs: if k == 'objId': # Can't test strings with np.test.assert_almost_equal. np.testing.assert_equal(chebyValues.coeffs[k], chebyValues2.coeffs[k]) else: # All of these will only be accurate to 2 less decimal places than they are # print out with in chebyFits. Since vmag, delta and elongation only use 7 # decimal places, this means we can test to 5 decimal places for those. np.testing.assert_almost_equal(chebyValues.coeffs[k], chebyValues2.coeffs[k], decimal=5) def testGetEphemerides(self): # Test that getEphemerides works and is accurate. chebyValues = ChebyValues() #chebyValues.setCoefficients(self.chebyFits) chebyValues.readCoefficients(self.coeffFile) time = self.tStart + self.interval / 2.0 # Test for all objects. ephemerides = chebyValues.getEphemerides(time) pyephemerides = self.pyephems.generateEphemerides(time, obscode=807, timeScale='TAI', byObject=False) # RA and Dec should agree to 2.5mas (skyTolerance above) pos_residuals = np.sqrt((ephemerides['ra'] - pyephemerides['ra'][0]) ** 2 + (ephemerides['dec'] - pyephemerides['dec'][0]) ** 2) pos_residuals *= 3600.0 * 1000.0 self.assertTrue(np.max(pos_residuals) <= 2.5) # Let's just look at the max residuals in all quantities. for k in ('ra', 'dec', 'dradt', 'ddecdt', 'delta'): resids = np.abs(ephemerides[k] - pyephemerides[k][0]) print 'max diff ', k, np.max(resids) resids = np.abs(ephemerides['elongation'] - pyephemerides['solarelon'][0]) print 'max diff elongation', np.max(resids) resids = np.abs(ephemerides['vmag'] - pyephemerides['magV'][0]) print 'max diff vmag', np.max(resids) # Test this for a subset of the objects. objIds = self.orbits.orbits.objId.head(3).as_matrix() ephemerides = chebyValues.getEphemerides(time, objIds) self.assertEqual(len(ephemerides['ra']), 3)
class TestPyOrbEphemerides(unittest.TestCase): def setUp(self): self.testdir = os.path.join(getPackageDir('sims_movingObjects'), 'tests/orbits_testdata') self.orbits = Orbits() self.orbits.readOrbits(os.path.join(self.testdir, 'test_orbitsQ.des')) self.orbitsKEP = Orbits() self.orbitsKEP.readOrbits( os.path.join(self.testdir, 'test_orbitsA.des')) self.ephems = PyOrbEphemerides() self.ephems.setOrbits(self.orbits) self.len_ephems_basic = 11 self.len_ephems_full = 34 def tearDown(self): del self.orbits del self.orbitsKEP del self.ephems def testSetOrbits(self): # Test that we can set orbits. self.ephems.setOrbits(self.orbits) # Test that setting with an empty orbit object fails. # (Avoids hard-to-interpret errors from pyoorb). with self.assertRaises(ValueError): emptyOrb = Orbits() empty = pd.DataFrame([], columns=self.orbits.dataCols['KEP']) emptyOrb.setOrbits(empty) self.ephems.setOrbits(emptyOrb) def testConvertToOorbArray(self): # Check that orbital elements are converted. self.ephems._convertToOorbElem(self.orbits.orbits, self.orbits.orb_format) self.assertEqual(len(self.ephems.oorbElem), len(self.orbits)) self.assertEqual(self.ephems.oorbElem[0][7], 2) self.assertEqual(self.ephems.oorbElem[0][9], 3) self.assertEqual(self.ephems.oorbElem[0][1], self.orbits.orbits['q'][0]) # Test that we can convert KEP orbital elements too. self.ephems._convertToOorbElem(self.orbitsKEP.orbits, self.orbitsKEP.orb_format) self.assertEqual(len(self.ephems.oorbElem), len(self.orbitsKEP)) self.assertEqual(self.ephems.oorbElem[0][7], 3) self.assertEqual(self.ephems.oorbElem[0][1], self.orbitsKEP.orbits['a'][0]) def testConvertFromOorbArray(self): # Check that we can convert orbital elements TO oorb format and back # without losing info (except ObjId -- we will lose that unless we use updateOrbits.) self.ephems._convertToOorbElem(self.orbits.orbits, self.orbits.orb_format) newOrbits = Orbits() newOrbits.setOrbits(self.orbits.orbits) newOrbits.updateOrbits(self.ephems.convertFromOorbElem()) self.assertEqual(newOrbits, self.orbits) def testConvertTimes(self): times = np.arange(49353, 49353 + 10, 0.5) ephTimes = self.ephems._convertTimes(times, 'UTC') # Check that shape of ephTimes is correct. (times x 2) self.assertEqual(ephTimes.shape[0], len(times)) self.assertEqual(ephTimes.shape[1], 2) # Check that 'timescale' for ephTimes is correct. self.assertEqual(ephTimes[0][1], 1) ephTimes = self.ephems._convertTimes(times, 'TAI') self.assertEqual(ephTimes[0][1], 4) def testOorbEphemeris(self): self.ephems.setOrbits(self.orbits) times = np.arange(49353, 49353 + 3, 0.25) ephTimes = self.ephems._convertTimes(times) # Basic ephemerides. oorbEphs = self.ephems._generateOorbEphsBasic(ephTimes, obscode=807, ephMode='N') # Check that it returned the right sort of array. self.assertEqual( oorbEphs.shape, (len(self.ephems.oorbElem), len(times), self.len_ephems_basic)) # Full ephemerides oorbEphs = self.ephems._generateOorbEphsFull(ephTimes, obscode=807, ephMode='N') # Check that it returned the right sort of array. self.assertEqual( oorbEphs.shape, (len(self.ephems.oorbElem), len(times), self.len_ephems_full)) def testEphemeris(self): # Calculate and convert ephemerides. self.ephems.setOrbits(self.orbits) times = np.arange(49353, 49353 + 2, 0.3) ephTimes = self.ephems._convertTimes(times) oorbEphs = self.ephems._generateOorbEphsBasic(ephTimes, obscode=807) # Group by object, and check grouping. ephs = self.ephems._convertOorbEphsBasic(oorbEphs, byObject=True) self.assertEqual(len(ephs), len(self.orbits)) # Group by time, and check grouping. oorbEphs = self.ephems._generateOorbEphsBasic(ephTimes, obscode=807) ephs = self.ephems._convertOorbEphsBasic(oorbEphs, byObject=False) self.assertEqual(len(ephs), len(times)) # And test all-wrapped-up method: ephsAll = self.ephems.generateEphemerides(times, obscode=807, ephMode='N', ephType='basic', timeScale='UTC', byObject=False) np.testing.assert_equal(ephsAll, ephs) # Reset ephems to use KEP Orbits, and calculate new ephemerides. self.ephems.setOrbits(self.orbitsKEP) oorbEphs = self.ephems._generateOorbEphsBasic(ephTimes, obscode=807, ephMode='N') ephsKEP = self.ephems._convertOorbEphsBasic(oorbEphs, byObject=True) self.assertEqual(len(ephsKEP), len(self.orbitsKEP)) oorbEphs = self.ephems._generateOorbEphsBasic(ephTimes, obscode=807, ephMode='N') ephsKEP = self.ephems._convertOorbEphsBasic(oorbEphs, byObject=False) self.assertEqual(len(ephsKEP), len(times)) # And test all-wrapped-up method: ephsAllKEP = self.ephems.generateEphemerides(times, obscode=807, ephMode='N', ephType='basic', timeScale='UTC', byObject=False) np.testing.assert_equal(ephsAllKEP, ephsKEP)
class TestPyOrbEphemerides(unittest.TestCase): def setUp(self): self.testdir = os.path.join(getPackageDir('sims_movingObjects'), 'tests/orbits_testdata') self.orbits = Orbits() self.orbits.readOrbits(os.path.join(self.testdir, 'test_orbitsQ.des')) self.orbitsKEP = Orbits() self.orbitsKEP.readOrbits( os.path.join(self.testdir, 'test_orbitsA.des')) self.ephems = PyOrbEphemerides() def tearDown(self): del self.orbits del self.orbitsKEP del self.ephems def testSetOrbits(self): # Test that we can set orbits. self.ephems.setOrbits(self.orbits) assert_frame_equal(self.ephems.orbitObj.orbits, self.orbits.orbits) # Test that setting with something other than an Orbit object fails. with self.assertRaises(ValueError): self.ephems.setOrbits(self.orbits.orbits) # Test that setting with an empty orbit object fails. # (Avoids hard-to-interpret errors from pyoorb). with self.assertRaises(ValueError): emptyOrb = Orbits() empty = pd.DataFrame([], columns=self.orbits.dataCols['KEP']) emptyOrb.setOrbits(empty) self.ephems.setOrbits(emptyOrb) def testConvertToOorbArray(self): # Check that orbital elements are converted. self.ephems.orbitObj = self.orbits self.ephems._convertToOorbElem() self.assertEqual(len(self.ephems.oorbElem), len(self.orbits)) self.assertEqual(self.ephems.oorbElem[0][7], 2) self.assertEqual(self.ephems.oorbElem[0][9], 3) self.assertEqual(self.ephems.oorbElem[0][1], self.orbits.orbits['q'][0]) # Test that we can convert KEP orbital elements too. self.ephems.orbitObj = self.orbitsKEP self.ephems._convertToOorbElem() self.assertEqual(len(self.ephems.oorbElem), len(self.orbitsKEP)) self.assertEqual(self.ephems.oorbElem[0][7], 3) self.assertEqual(self.ephems.oorbElem[0][1], self.orbitsKEP.orbits['a'][0]) def testConvertFromOorbArray(self): self.ephems.orbitObj = self.orbits self.ephems._convertToOorbElem() newOrbits = self.ephems._convertFromOorbElem(self.ephems.oorbElem) self.assertEqual(newOrbits, self.orbits) def testConvertTimes(self): times = np.arange(49353, 49353 + 10, 0.5) ephTimes = self.ephems._convertTimes(times, 'UTC') # Check that shape of ephTimes is correct. self.assertEqual(ephTimes.shape[0], len(times)) self.assertEqual(ephTimes.shape[1], 2) # Check that 'timescale' for ephTimes is correct. self.assertEqual(ephTimes[0][1], 1) ephTimes = self.ephems._convertTimes(times, 'TAI') self.assertEqual(ephTimes[0][1], 4) def testOorbEphemeris(self): self.ephems.setOrbits(self.orbits) times = np.arange(49353, 49353 + 3, 0.25) ephTimes = self.ephems._convertTimes(times) oorbEphs = self.ephems._generateOorbEphs(ephTimes, obscode=807) # Check that it returned the right sort of array. self.assertEqual(oorbEphs.shape, (len(self.ephems.oorbElem), len(times), 10)) def testEphemeris(self): # Calculate and convert ephemerides. self.ephems.setOrbits(self.orbits) times = np.arange(49353, 49353 + 2, 0.3) ephTimes = self.ephems._convertTimes(times) oorbEphs = self.ephems._generateOorbEphs(ephTimes, obscode=807) # Group by object, and check grouping. ephs = self.ephems._convertOorbEphs(oorbEphs, byObject=True) self.assertEqual(len(ephs), len(self.orbits)) # Group by time, and check grouping. ephs = self.ephems._convertOorbEphs(oorbEphs, byObject=False) self.assertEqual(len(ephs), len(times)) # And test all-wrapped-up method: ephsAll = self.ephems.generateEphemerides(times, obscode=807, timeScale='UTC', byObject=False) np.testing.assert_equal(ephsAll, ephs) # Reset ephems to use KEP Orbits, and calculate new ephemerides. self.ephems.setOrbits(self.orbitsKEP) oorbEphs = self.ephems._generateOorbEphs(ephTimes, obscode=807) ephsKEP = self.ephems._convertOorbEphs(oorbEphs, byObject=True) self.assertEqual(len(ephsKEP), len(self.orbitsKEP)) ephsKEP = self.ephems._convertOorbEphs(oorbEphs, byObject=False) self.assertEqual(len(ephsKEP), len(times)) # Check that ephemerides calculated by each method are almost equal. for column in ephs.dtype.names: np.testing.assert_allclose(ephs[column], ephsKEP[column], rtol=0, atol=1e-7) # And test all-wrapped-up method: ephsAllKEP = self.ephems.generateEphemerides(times, obscode=807, timeScale='UTC', byObject=False) np.testing.assert_equal(ephsAllKEP, ephsKEP) # Check that the wrapped method using KEP elements and the wrapped method using COM elements match. for column in ephsAll.dtype.names: np.testing.assert_allclose(ephsAllKEP[column], ephsAll[column], rtol=0, atol=1e-7)
class TestChebyValues(unittest.TestCase): def setUp(self): self.testdatadir = os.path.join(getPackageDir('sims_movingObjects'), 'tests/orbits_testdata') self.scratch_dir = tempfile.mkdtemp(dir=ROOT, prefix='TestChebyValues-') self.coeffFile = os.path.join(self.scratch_dir, 'test_coeffs') self.residFile = os.path.join(self.scratch_dir, 'test_resids') self.failedFile = os.path.join(self.scratch_dir, 'test_failed') self.orbits = Orbits() self.orbits.readOrbits(os.path.join(self.testdatadir, 'test_orbitsNEO.s3m'), skiprows=1) self.pyephems = PyOrbEphemerides(os.path.join(os.getenv('OORB_DATA'), 'DE405.dat')) self.pyephems.setOrbits(self.orbits) self.tStart = self.orbits.orbits.epoch.iloc[0] self.interval = 30 self.nCoeffs = 14 self.nDecimal = 13 self.chebyFits = ChebyFits(self.orbits, self.tStart, self.interval, ngran=64, skyTolerance=2.5, nDecimal=self.nDecimal, nCoeff_position=self.nCoeffs, obscode=807, timeScale='TAI') self.setLength = 0.5 self.chebyFits.calcSegmentLength(length=self.setLength) self.chebyFits.calcSegments() self.chebyFits.write(self.coeffFile, self.residFile, self.failedFile, append=False) self.coeffKeys = ['objId', 'tStart', 'tEnd', 'ra', 'dec', 'geo_dist', 'vmag', 'elongation'] def tearDown(self): del self.orbits del self.chebyFits if os.path.exists(self.scratch_dir): shutil.rmtree(self.scratch_dir) def testSetCoeff(self): # Test setting coefficients directly from chebyFits outputs. chebyValues = ChebyValues() chebyValues.setCoefficients(self.chebyFits) for k in self.coeffKeys: self.assertTrue(k in chebyValues.coeffs) self.assertTrue(isinstance(chebyValues.coeffs[k], np.ndarray)) self.assertEqual(len(np.unique(chebyValues.coeffs['objId'])), len(self.orbits)) # This will only be true for carefully selected length/orbit type, where subdivision did not occur. # For the test MBAs, a len=1day will work. # For the test NEOs, a len=0.25 day will work (with 2.5mas skyTol). # self.assertEqual(len(chebyValues.coeffs['tStart']), # (self.interval / self.setLength) * len(self.orbits)) self.assertEqual(len(chebyValues.coeffs['ra'][0]), self.nCoeffs) self.assertTrue('meanRA' in chebyValues.coeffs) self.assertTrue('meanDec' in chebyValues.coeffs) def testReadCoeffs(self): # Test reading the coefficients from disk. chebyValues = ChebyValues() chebyValues.readCoefficients(self.coeffFile) chebyValues2 = ChebyValues() chebyValues2.setCoefficients(self.chebyFits) for k in chebyValues.coeffs: if k == 'objId': # Can't test strings with np.test.assert_almost_equal. np.testing.assert_equal(chebyValues.coeffs[k], chebyValues2.coeffs[k]) else: # All of these will only be accurate to 2 less decimal places than they are # print out with in chebyFits. Since vmag, delta and elongation only use 7 # decimal places, this means we can test to 5 decimal places for those. np.testing.assert_allclose(chebyValues.coeffs[k], chebyValues2.coeffs[k], rtol=0, atol=1e-5) def testGetEphemerides(self): # Test that getEphemerides works and is accurate. chebyValues = ChebyValues() chebyValues.readCoefficients(self.coeffFile) # Multiple times, all objects, all within interval. tstep = self.interval/10.0 time = np.arange(self.tStart, self.tStart + self.interval, tstep) # Test for a single time, but all the objects. ephemerides = chebyValues.getEphemerides(time) pyephemerides = self.pyephems.generateEphemerides(time, obscode=807, timeScale='TAI', byObject=True) # RA and Dec should agree to 2.5mas (skyTolerance above) pos_residuals = np.sqrt((ephemerides['ra'] - pyephemerides['ra']) ** 2 + ((ephemerides['dec'] - pyephemerides['dec']) * np.cos(np.radians(ephemerides['dec']))) ** 2) pos_residuals *= 3600.0 * 1000.0 # Let's just look at the max residuals in all quantities. for k in ('ra', 'dec', 'dradt', 'ddecdt', 'geo_dist'): resids = np.abs(ephemerides[k] - pyephemerides[k]) if k != 'geo_dist': resids *= 3600.0 * 1000.0 print('max diff', k, np.max(resids)) resids = np.abs(ephemerides['elongation'] - pyephemerides['solarelon']) print('max diff elongation', np.max(resids)) resids = np.abs(ephemerides['vmag'] - pyephemerides['magV']) print('max diff vmag', np.max(resids)) self.assertLessEqual(np.max(pos_residuals), 2.5) # Test for single time, but for a subset of the objects. objIds = self.orbits.orbits.objId.head(3).as_matrix() ephemerides = chebyValues.getEphemerides(time, objIds) self.assertEqual(len(ephemerides['ra']), 3) # Test for time outside of segment range. ephemerides = chebyValues.getEphemerides(self.tStart + self.interval * 2, objIds, extrapolate=False) self.assertTrue(np.isnan(ephemerides['ra'][0]), msg='Expected Nan for out of range ephemeris, got %.2e' %(ephemerides['ra'][0]))
class TestPyOrbEphemerides(unittest.TestCase): def setUp(self): self.testdir = os.path.join(getPackageDir('sims_movingObjects'), 'tests/orbits_testdata') self.orbits = Orbits() self.orbits.readOrbits(os.path.join(self.testdir, 'test_orbitsQ.des')) self.orbitsKEP = Orbits() self.orbitsKEP.readOrbits(os.path.join(self.testdir, 'test_orbitsA.des')) self.ephems = PyOrbEphemerides() def tearDown(self): del self.orbits del self.orbitsKEP del self.ephems def testSetOrbits(self): # Test that we can set orbits. self.ephems.setOrbits(self.orbits) assert_frame_equal(self.ephems.orbitObj.orbits, self.orbits.orbits) # Test that setting with something other than an Orbit object fails. with self.assertRaises(ValueError): self.ephems.setOrbits(self.orbits.orbits) # Test that setting with an empty orbit object fails. # (Avoids hard-to-interpret errors from pyoorb). with self.assertRaises(ValueError): emptyOrb = Orbits() empty = pd.DataFrame([], columns=self.orbits.dataCols['KEP']) emptyOrb.setOrbits(empty) self.ephems.setOrbits(emptyOrb) def testConvertToOorbArray(self): # Check that orbital elements are converted. self.ephems.orbitObj = self.orbits self.ephems._convertToOorbElem() self.assertEqual(len(self.ephems.oorbElem), len(self.orbits)) self.assertEqual(self.ephems.oorbElem[0][7], 2) self.assertEqual(self.ephems.oorbElem[0][9], 3) self.assertEqual(self.ephems.oorbElem[0][1], self.orbits.orbits['q'][0]) # Test that we can convert KEP orbital elements too. self.ephems.orbitObj = self.orbitsKEP self.ephems._convertToOorbElem() self.assertEqual(len(self.ephems.oorbElem), len(self.orbitsKEP)) self.assertEqual(self.ephems.oorbElem[0][7], 3) self.assertEqual(self.ephems.oorbElem[0][1], self.orbitsKEP.orbits['a'][0]) def testConvertFromOorbArray(self): self.ephems.orbitObj = self.orbits self.ephems._convertToOorbElem() newOrbits = self.ephems._convertFromOorbElem(self.ephems.oorbElem) self.assertEqual(newOrbits, self.orbits) def testConvertTimes(self): times = np.arange(49353, 49353 + 10, 0.5) ephTimes = self.ephems._convertTimes(times, 'UTC') # Check that shape of ephTimes is correct. self.assertEqual(ephTimes.shape[0], len(times)) self.assertEqual(ephTimes.shape[1], 2) # Check that 'timescale' for ephTimes is correct. self.assertEqual(ephTimes[0][1], 1) ephTimes = self.ephems._convertTimes(times, 'TAI') self.assertEqual(ephTimes[0][1], 4) def testOorbEphemeris(self): self.ephems.setOrbits(self.orbits) times = np.arange(49353, 49353 + 3, 0.25) ephTimes = self.ephems._convertTimes(times) oorbEphs = self.ephems._generateOorbEphs(ephTimes, obscode=807) # Check that it returned the right sort of array. self.assertEqual(oorbEphs.shape, (len(self.ephems.oorbElem), len(times), 10)) def testEphemeris(self): # Calculate and convert ephemerides. self.ephems.setOrbits(self.orbits) times = np.arange(49353, 49353 + 2, 0.3) ephTimes = self.ephems._convertTimes(times) oorbEphs = self.ephems._generateOorbEphs(ephTimes, obscode=807) # Group by object, and check grouping. ephs = self.ephems._convertOorbEphs(oorbEphs, byObject=True) self.assertEqual(len(ephs), len(self.orbits)) # Group by time, and check grouping. ephs = self.ephems._convertOorbEphs(oorbEphs, byObject=False) self.assertEqual(len(ephs), len(times)) # And test all-wrapped-up method: ephsAll = self.ephems.generateEphemerides(times, obscode=807, timeScale='UTC', byObject=False) np.testing.assert_equal(ephsAll, ephs) # Reset ephems to use KEP Orbits, and calculate new ephemerides. self.ephems.setOrbits(self.orbitsKEP) oorbEphs = self.ephems._generateOorbEphs(ephTimes, obscode=807) ephsKEP = self.ephems._convertOorbEphs(oorbEphs, byObject=True) self.assertEqual(len(ephsKEP), len(self.orbitsKEP)) ephsKEP = self.ephems._convertOorbEphs(oorbEphs, byObject=False) self.assertEqual(len(ephsKEP), len(times)) # Check that ephemerides calculated by each method are almost equal. for column in ephs.dtype.names: np.testing.assert_allclose(ephs[column], ephsKEP[column], rtol=0, atol=1e-7) # And test all-wrapped-up method: ephsAllKEP = self.ephems.generateEphemerides(times, obscode=807, timeScale='UTC', byObject=False) np.testing.assert_equal(ephsAllKEP, ephsKEP) # Check that the wrapped method using KEP elements and the wrapped method using COM elements match. for column in ephsAll.dtype.names: np.testing.assert_allclose(ephsAllKEP[column], ephsAll[column], rtol=0, atol=1e-7)
times = np.array(args.ephTimes.split(), float) obshistids = np.arange(0, len(times)) elif args.ephTimesFile is not None: times = pd.read_table(args.ephTimesFile, delim_whitespace=True, names=['times']) times = times['times'].values else: raise Exception('Did not have any ephemeride times') #print "Using times: ", times # Generate ephemerides. pyephems.setOrbits(orbits) ephs = pyephems.generateEphemerides(times, obscode=obscode, timeScale='TAI', ephMode='N', byObject=True) print( 'ObjId MJD(TAI) RA Dec dRAdt dDecdt Geo_Dist Helio_Dist magV Elongation' ) for e, o in zip(ephs, orbits): for i in range(len(e)): print(o.orbits.objId.iloc[0], e['time'][i], e['ra'][i], e['dec'][i], e['dradt'][i], e['ddecdt'][i], e['geo_dist'][i], e['helio_dist'][i], e['magV'][i], e['solarelon'][i])