def testConvertFromVel(self): """Test velocity of convertFrom """ taiDate = 4889900000.205 site = coordConv.Site(-105.822616, 32.780988, 2788) icrsCoordSys = coordConv.ICRSCoordSys() appTopoCoordSys = coordConv.AppTopoCoordSys() # find ICRS coordinate of a sidereal point on the equator along the meridion appTopoCoord = coordConv.Coord(0, 90 - site.meanLat) icrsCoord = icrsCoordSys.convertFrom(appTopoCoordSys, appTopoCoord, site, taiDate) icrsPVTCoord = coordConv.PVTCoord(icrsCoord, icrsCoord, taiDate, 0.001) appTopoPVTCoord = appTopoCoordSys.convertFrom(icrsCoordSys, icrsPVTCoord, site) equatPVT = coordConv.PVT() polarPVT = coordConv.PVT() appTopoPVTCoord.getSphPVT(equatPVT, polarPVT) self.assertEqual(equatPVT.t, taiDate) self.assertEqual(polarPVT.t, taiDate) equatSpaceVel = equatPVT.vel * coordConv.cosd(polarPVT.pos) self.assertAlmostEqual(polarPVT.vel, 0, places=3) self.assertAlmostEqual(equatSpaceVel, -1/240.0, places=3) # 360 deg/day # check round trip of scale and orientation for fromDir in (0, 45): for fromVel in (0, 0.01): fromDirPVT = coordConv.PVT(fromDir, fromVel, taiDate) toDirPVT = coordConv.PVT() fromDir2PVT = coordConv.PVT() at2PVTCoord, scaleChange = appTopoCoordSys.convertFrom(toDirPVT, icrsCoordSys, icrsPVTCoord, fromDirPVT, site) icrs2PVTCoord, scaleChange2 = icrsCoordSys.convertFrom(fromDir2PVT, appTopoCoordSys, at2PVTCoord, toDirPVT, site) self.assertAlmostEqual(scaleChange, 1.0/scaleChange2, places=7) coordConv.assertPVTsAlmostEqual(fromDirPVT, fromDir2PVT, doWrap=True, velPlaces=6)
def testLunarVel(self): """Sanity-check lunar tracking velocity This checks for an issue we had with tracking close objects: position was right, but velocity was not. This was because Apparent Geocentric date was not being updated inside the PVTCoord version of CoordSys.convertFrom. """ tai = 4914602887 dt = 0.1 site = coordConv.Site(-105.822616, 32.780988, 2788) geoCoordSys = coordConv.AppGeoCoordSys() topoCoordSys = coordConv.AppTopoCoordSys() geoCoord = coordConv.Coord(0, 75, 82505922) topoPVTList = [] for evalTAI in (tai, tai + dt): geoPVTCoord = coordConv.PVTCoord(geoCoord, geoCoord, evalTAI, 0.01) topoPVTCoord = topoCoordSys.convertFrom(geoCoordSys, geoPVTCoord, site) topoPVTPair = [coordConv.PVT() for i in range(2)] topoPVTCoord.getSphPVT(topoPVTPair[0], topoPVTPair[1]) topoPVTList.append(topoPVTPair) for i in range(2): pvt0 = topoPVTList[0][i] pvt1 = topoPVTList[1][i] coordConv.assertPVTsAlmostEqual(pvt0.copy(pvt1.t), pvt1)
def testAngularSeparation(self): """Test PVTCoord.angularSeparation and orientationTo """ def pvtCoordIter(): for equatAng in (0, 71, -123.4): for polarAng in (0, -75, -89.99999, -90, 89.99999): for equatVel in (0, 0.023): for polarVel in (0, -math.copysign(0.012, polarAng)): for tai in (4889100000.5, 1000.1): equatPVT = coordConv.PVT(equatAng, equatVel, tai) polarPVT = coordConv.PVT(polarAng, polarVel, tai) yield coordConv.PVTCoord(equatPVT, polarPVT) def refAngularSeparation(pvtCoord0, pvtCoord1): """Compute angular separation between pvtCoord0, pvtCoord1 using Coord.angularSeparation """ tai = pvtCoord0.getTAI() DeltaT = 0.01 posList = [] for tempTAI in (tai, tai + DeltaT): coord0 = pvtCoord0.getCoord(tempTAI) coord1 = pvtCoord1.getCoord(tempTAI) posList.append(coord0.angularSeparation(coord1)) return makePVTFromPair(posList, tai, DeltaT, True) def refOrientTo(pvtCoord0, pvtCoord1): """Compute orientation from pvtCoord0 to pvtCoord1 using Coord.orientationTo """ tai = pvtCoord0.getTAI() DeltaT = 0.01 posList = [] for tempTAI in (tai, tai + DeltaT): coord0 = pvtCoord0.getCoord(tempTAI) coord1 = pvtCoord1.getCoord(tempTAI) posList.append(coord0.orientationTo(coord1)) if numpy.all(numpy.isfinite(posList)): return makePVTFromPair(posList, tai, DeltaT, True) elif numpy.isfinite(posList[0]): return coordConv.PVT(posList[0], 0, tai) elif numpy.isfinite(posList[1]): return coordConv.PVT(posList[1], 0, tai) else: return coordConv.PVT() for pvtCoord0 in pvtCoordIter(): for pvtCoord1 in pvtCoordIter(): angSep = pvtCoord0.angularSeparation(pvtCoord1) refAngSep = refAngularSeparation(pvtCoord0, pvtCoord1) coordConv.assertPVTsAlmostEqual(angSep, refAngSep) if pvtCoord0 == pvtCoord1: self.assertAlmostEqual(angSep.pos, 0) self.assertAlmostEqual(angSep.vel, 0) orient = pvtCoord0.orientationTo(pvtCoord1) refOrient = refOrientTo(pvtCoord0, pvtCoord1) if not orient.isfinite(): self.assertFalse(refOrient.isfinite()) else: coordConv.assertPVTsAlmostEqual(orient, refOrient, doWrap=True)
def testTwoPVTConstructors(self): """Test both two-PVT constructors: PVTCoord(equatPVT, polarPVT, tai, distPVT) PVTCoord(equatPVT, polarPVT, tai, distPVT, equatPM, polarPM, radVel, defOrient) """ for equatAng in (0, 71, -123.4): for polarAng in (0, -75, -89.99, 89.99): for orient in (0, -45, 31.23): sinOrient = coordConv.sind(orient) cosOrient = coordConv.cosd(orient) for vel in (0, 0.1, 0.23): for tai in (500.5, 10001.3): # coord0 = coordConv.Coord(equatAng, polarAng) polarVel = vel * sinOrient equatVel = vel * cosOrient / coordConv.cosd(polarAng) equatPVT = coordConv.PVT(equatAng, equatVel, tai) polarPVT = coordConv.PVT(polarAng, polarVel, tai) pvtCoord = coordConv.PVTCoord(equatPVT, polarPVT) self.assertAlmostEqual(pvtCoord.getTAI(), tai) self.assertTrue(pvtCoord.isfinite()) gotEquatPVT = coordConv.PVT() gotPolarPVT = coordConv.PVT() pvtCoord.getSphPVT(gotEquatPVT, gotPolarPVT) coordConv.assertPVTsAlmostEqual(equatPVT, gotEquatPVT, doWrap=True) coordConv.assertPVTsAlmostEqual(polarPVT, gotPolarPVT, doWrap=False) for parallax in (0, 0.012): dist = coordConv.distanceFromParallax(parallax) for distVel in (0, 10000): distPVT = coordConv.PVT(dist, distVel, tai) for equatPM in (0, 0.11): for polarPM in (0, -0.12): for radVel in (0, 0.13): pvtCoordPM = coordConv.PVTCoord(equatPVT, polarPVT, distPVT, equatPM, polarPM, radVel) self.assertAlmostEqual(pvtCoordPM.getTAI(), tai) self.assertTrue(pvtCoordPM.isfinite()) gotEquatPVT = coordConv.PVT() gotPolarPVT = coordConv.PVT() pvtCoordPM.getSphPVT(gotEquatPVT, gotPolarPVT) coordConv.assertPVTsAlmostEqual(equatPVT, gotEquatPVT, doWrap=True) coordConv.assertPVTsAlmostEqual(polarPVT, gotPolarPVT, doWrap=False) coordToCheck = pvtCoordPM.getCoord() self.assertAlmostEqual(radVel, coordToCheck.getRadVel()) atPole, checkEquatPM, checkPolarPM = coordToCheck.getPM() if not atPole: self.assertAlmostEqual(equatPM, checkEquatPM) self.assertAlmostEqual(polarPM, checkPolarPM) self.assertAlmostEqual(parallax, coordToCheck.getParallax()) if parallax != 0: self.assertAlmostEqual(dist, coordToCheck.getDistance(), places=5) coordConv.assertPVTsAlmostEqual(distPVT, pvtCoordPM.getDistance(), velPlaces = 5, posPlaces=5)
def testPVTsAlmostEqual(self): for (posPlaces, velPlaces, tPlaces) in ( (5, 6, 7), (6, 7, 5), ): maxPosErr = 10**-posPlaces maxVelErr = 10**-velPlaces maxTErr = 10**-tPlaces for pvt1 in ( coordConv.PVT(5, 0.2, 3543), coordConv.PVT(386, -230.3, 5923402.22), ): for nWrap in (0, -3, 1): if nWrap == 0: doWrapList = (False, True) else: doWrapList = (True, ) wrappedPVT = pvt1.copy() wrappedPVT.pos += 360.0 * nWrap posEps = wrappedPVT.pos * 1e-14 velEps = pvt1.vel * 1e-14 tEps = pvt1.t * 1e-14 for deltaPos in (maxPosErr - posEps, maxPosErr + posEps): for deltaVel in (maxVelErr - velEps, maxVelErr + velEps): for deltaT in (maxTErr - tEps, maxTErr + tEps): pvt2 = wrappedPVT.copy() pvt2.pos += deltaPos pvt2.vel += deltaVel pvt2.t += deltaT for doWrap in doWrapList: if abs(deltaPos) <= maxPosErr \ and abs(deltaVel) <= maxVelErr \ and abs(deltaT) <= maxTErr: coordConv.assertPVTsAlmostEqual( pvt1, pvt2, doWrap=doWrap, posPlaces=posPlaces, velPlaces=velPlaces, tPlaces=tPlaces, ) else: self.assertRaises( AssertionError, coordConv.assertPVTsAlmostEqual, pvt1, pvt2, doWrap=doWrap, posPlaces=posPlaces, velPlaces=velPlaces, tPlaces=tPlaces, )
def testPVTsAlmostEqual(self): for (posPlaces, velPlaces, tPlaces) in ( (5, 6, 7), (6, 7, 5), ): maxPosErr = 10**-posPlaces maxVelErr = 10**-velPlaces maxTErr = 10**-tPlaces for pvt1 in ( coordConv.PVT(5, 0.2, 3543), coordConv.PVT(386, -230.3, 5923402.22), ): for nWrap in (0, -3, 1): if nWrap == 0: doWrapList = (False, True) else: doWrapList = (True,) wrappedPVT = pvt1.copy() wrappedPVT.pos += 360.0 * nWrap posEps = wrappedPVT.pos * 1e-14 velEps = pvt1.vel * 1e-14 tEps = pvt1.t * 1e-14 for deltaPos in (maxPosErr - posEps, maxPosErr + posEps): for deltaVel in (maxVelErr - velEps, maxVelErr + velEps): for deltaT in (maxTErr - tEps, maxTErr + tEps): pvt2 = wrappedPVT.copy() pvt2.pos += deltaPos pvt2.vel += deltaVel pvt2.t += deltaT for doWrap in doWrapList: if abs(deltaPos) <= maxPosErr \ and abs(deltaVel) <= maxVelErr \ and abs(deltaT) <= maxTErr: coordConv.assertPVTsAlmostEqual( pvt1, pvt2, doWrap = doWrap, posPlaces = posPlaces, velPlaces = velPlaces, tPlaces = tPlaces, ) else: self.assertRaises( AssertionError, coordConv.assertPVTsAlmostEqual, pvt1, pvt2, doWrap = doWrap, posPlaces = posPlaces, velPlaces = velPlaces, tPlaces = tPlaces, )
def testConvertFromVel(self): """Test velocity of convertFrom """ taiDate = 4889900000.205 site = coordConv.Site(-105.822616, 32.780988, 2788) icrsCoordSys = coordConv.ICRSCoordSys() appTopoCoordSys = coordConv.AppTopoCoordSys() # find ICRS coordinate of a sidereal point on the equator along the meridion appTopoCoord = coordConv.Coord(0, 90 - site.meanLat) icrsCoord = icrsCoordSys.convertFrom(appTopoCoordSys, appTopoCoord, site, taiDate) icrsPVTCoord = coordConv.PVTCoord(icrsCoord, icrsCoord, taiDate, 0.001) appTopoPVTCoord = appTopoCoordSys.convertFrom(icrsCoordSys, icrsPVTCoord, site) equatPVT = coordConv.PVT() polarPVT = coordConv.PVT() appTopoPVTCoord.getSphPVT(equatPVT, polarPVT) self.assertEqual(equatPVT.t, taiDate) self.assertEqual(polarPVT.t, taiDate) equatSpaceVel = equatPVT.vel * coordConv.cosd(polarPVT.pos) self.assertAlmostEqual(polarPVT.vel, 0, places=3) self.assertAlmostEqual(equatSpaceVel, -1 / 240.0, places=3) # 360 deg/day # check round trip of scale and orientation for fromDir in (0, 45): for fromVel in (0, 0.01): fromDirPVT = coordConv.PVT(fromDir, fromVel, taiDate) toDirPVT = coordConv.PVT() fromDir2PVT = coordConv.PVT() at2PVTCoord, scaleChange = appTopoCoordSys.convertFrom( toDirPVT, icrsCoordSys, icrsPVTCoord, fromDirPVT, site) icrs2PVTCoord, scaleChange2 = icrsCoordSys.convertFrom( fromDir2PVT, appTopoCoordSys, at2PVTCoord, toDirPVT, site) self.assertAlmostEqual(scaleChange, 1.0 / scaleChange2, places=7) coordConv.assertPVTsAlmostEqual(fromDirPVT, fromDir2PVT, doWrap=True, velPlaces=6)
def testAngularSeparation(self): """Test PVTCoord.angularSeparation and orientationTo """ def pvtCoordIter(): for equatAng in (0, 71, -123.4): for polarAng in (0, -75, -89.99999, -90, 89.99999): for equatVel in (0, 0.023): for polarVel in (0, -math.copysign(0.012, polarAng)): for tai in (4889100000.5, 1000.1): equatPVT = coordConv.PVT( equatAng, equatVel, tai) polarPVT = coordConv.PVT( polarAng, polarVel, tai) yield coordConv.PVTCoord(equatPVT, polarPVT) def refAngularSeparation(pvtCoord0, pvtCoord1): """Compute angular separation between pvtCoord0, pvtCoord1 using Coord.angularSeparation """ tai = pvtCoord0.getTAI() DeltaT = 0.01 posList = [] for tempTAI in (tai, tai + DeltaT): coord0 = pvtCoord0.getCoord(tempTAI) coord1 = pvtCoord1.getCoord(tempTAI) posList.append(coord0.angularSeparation(coord1)) return makePVTFromPair(posList, tai, DeltaT, True) def refOrientTo(pvtCoord0, pvtCoord1): """Compute orientation from pvtCoord0 to pvtCoord1 using Coord.orientationTo """ tai = pvtCoord0.getTAI() DeltaT = 0.01 posList = [] for tempTAI in (tai, tai + DeltaT): coord0 = pvtCoord0.getCoord(tempTAI) coord1 = pvtCoord1.getCoord(tempTAI) posList.append(coord0.orientationTo(coord1)) if numpy.all(numpy.isfinite(posList)): return makePVTFromPair(posList, tai, DeltaT, True) elif numpy.isfinite(posList[0]): return coordConv.PVT(posList[0], 0, tai) elif numpy.isfinite(posList[1]): return coordConv.PVT(posList[1], 0, tai) else: return coordConv.PVT() for pvtCoord0 in pvtCoordIter(): for pvtCoord1 in pvtCoordIter(): angSep = pvtCoord0.angularSeparation(pvtCoord1) refAngSep = refAngularSeparation(pvtCoord0, pvtCoord1) coordConv.assertPVTsAlmostEqual(angSep, refAngSep) if pvtCoord0 == pvtCoord1: self.assertAlmostEqual(angSep.pos, 0) self.assertAlmostEqual(angSep.vel, 0) orient = pvtCoord0.orientationTo(pvtCoord1) refOrient = refOrientTo(pvtCoord0, pvtCoord1) if not orient.isfinite(): self.assertFalse(refOrient.isfinite()) else: coordConv.assertPVTsAlmostEqual(orient, refOrient, doWrap=True)
def testTwoPVTConstructors(self): """Test both two-PVT constructors: PVTCoord(equatPVT, polarPVT, tai, distPVT) PVTCoord(equatPVT, polarPVT, tai, distPVT, equatPM, polarPM, radVel, defOrient) """ for equatAng in (0, 71, -123.4): for polarAng in (0, -75, -89.99, 89.99): for orient in (0, -45, 31.23): sinOrient = coordConv.sind(orient) cosOrient = coordConv.cosd(orient) for vel in (0, 0.1, 0.23): for tai in (500.5, 10001.3): # coord0 = coordConv.Coord(equatAng, polarAng) polarVel = vel * sinOrient equatVel = vel * cosOrient / coordConv.cosd( polarAng) equatPVT = coordConv.PVT(equatAng, equatVel, tai) polarPVT = coordConv.PVT(polarAng, polarVel, tai) pvtCoord = coordConv.PVTCoord(equatPVT, polarPVT) self.assertAlmostEqual(pvtCoord.getTAI(), tai) self.assertTrue(pvtCoord.isfinite()) gotEquatPVT = coordConv.PVT() gotPolarPVT = coordConv.PVT() pvtCoord.getSphPVT(gotEquatPVT, gotPolarPVT) coordConv.assertPVTsAlmostEqual(equatPVT, gotEquatPVT, doWrap=True) coordConv.assertPVTsAlmostEqual(polarPVT, gotPolarPVT, doWrap=False) for parallax in (0, 0.012): dist = coordConv.distanceFromParallax(parallax) for distVel in (0, 10000): distPVT = coordConv.PVT(dist, distVel, tai) for equatPM in (0, 0.11): for polarPM in (0, -0.12): for radVel in (0, 0.13): pvtCoordPM = coordConv.PVTCoord( equatPVT, polarPVT, distPVT, equatPM, polarPM, radVel) self.assertAlmostEqual( pvtCoordPM.getTAI(), tai) self.assertTrue( pvtCoordPM.isfinite()) gotEquatPVT = coordConv.PVT() gotPolarPVT = coordConv.PVT() pvtCoordPM.getSphPVT( gotEquatPVT, gotPolarPVT) coordConv.assertPVTsAlmostEqual( equatPVT, gotEquatPVT, doWrap=True) coordConv.assertPVTsAlmostEqual( polarPVT, gotPolarPVT, doWrap=False) coordToCheck = pvtCoordPM.getCoord( ) self.assertAlmostEqual( radVel, coordToCheck.getRadVel()) atPole, checkEquatPM, checkPolarPM = coordToCheck.getPM( ) if not atPole: self.assertAlmostEqual( equatPM, checkEquatPM) self.assertAlmostEqual( polarPM, checkPolarPM) self.assertAlmostEqual( parallax, coordToCheck.getParallax()) if parallax != 0: self.assertAlmostEqual( dist, coordToCheck. getDistance(), places=5) coordConv.assertPVTsAlmostEqual( distPVT, pvtCoordPM.getDistance( ), velPlaces=5, posPlaces=5)