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))
 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 setUp(self):
     self.testdir = 'orbits_testdata'
     self.orbits = Orbits()
     self.orbits.readOrbits(os.path.join(self.testdir, 'test_orbitsQ.des'))
     self.orbitsA = Orbits()
     self.orbitsA.readOrbits(os.path.join(self.testdir, 'test_orbitsA.des'))
     self.ephems = PyOrbEphemerides()
 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 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']
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)
Beispiel #7
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()
        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)
Beispiel #9
0
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)
Beispiel #11
0
        type=str,
        default=None,
        help=
        'List of MJD times for ephemerides (if >1: in quotes, separated by spaces'
    )
    parser.set_defaults()
    args = parser.parse_args()

    # Read orbits.
    orbits = Orbits()
    orbits.readOrbits(args.orbitFile)
    print('Read %d orbits, first one with epoch of %f.' %
          (len(orbits), orbits.orbits.epoch.iloc[0]))

    # Set up ephemeris generation.
    pyephems = PyOrbEphemerides()

    print(pyephems.ephfile)
    # set observatory code
    obscode = args.obsCode

    # Set up dates to predict ephemerides.
    if args.ephTimes is not None:
        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