def testWrap(self):
        for wrap in (-1000, -10, -1, 0, 1, 10, 1000):
            for offset in (-360, -180, -90, 0, 90, 180, 270, 360):
                for epsMult in (-3, -2, -1, 0, 1, 2, 3):
                    ang = offset + (wrap * 360)
                    ang += ang * DoubleEpsilon * epsMult
                    sinAng = sind(ang)
                    cosAng = cosd(ang)
                    pvt = PVT(ang, ang, 35.0) # pick anything for vel and time

                    posAng = wrapPos(ang)
                    self.assertGreaterEqual(posAng, 0.0)
                    self.assertLess(posAng, 360.0)
                    # prove that posAng and ang are the same angle
                    # sin and cos are a sanity check on wrapCtr
                    self.assertAlmostEqual(wrapCtr(posAng - ang), 0)
                    self.assertAlmostEqual(sind(posAng), sinAng)
                    self.assertAlmostEqual(cosd(posAng), cosAng)

                    posPvt = wrapPos(pvt)
                    self.assertEqual(posPvt.pos, posAng)
                    self.assertEqual(posPvt.vel, pvt.vel)
                    self.assertEqual(posPvt.t, pvt.t)

                    ctrAng = wrapCtr(ang)
                    self.assertGreaterEqual(ctrAng, -180.0)
                    self.assertLess(ctrAng, 180.0)
                    # prove that ctrAng and ang are the same angle
                    self.assertAlmostEqual(wrapCtr(ctrAng - ang), 0)
                    self.assertAlmostEqual(sind(ctrAng), sinAng)
                    self.assertAlmostEqual(cosd(ctrAng), cosAng)

                    ctrPvt = wrapCtr(pvt)
                    self.assertEqual(ctrPvt.pos, ctrAng)
                    self.assertEqual(ctrPvt.vel, pvt.vel)
                    self.assertEqual(ctrPvt.t, pvt.t)
                    
                    for refAngBase in (-180, 0, 180, 360):
                        for refEpsMult in (-3, -2, -1, 0, 1, 2, 3):
                            refAng = refAngBase
                            refAng += refAng * refEpsMult * DoubleEpsilon
                            nearAng = wrapNear(ang, refAng)
                            self.assertGreaterEqual(nearAng - refAng, -180)
                            self.assertLess(nearAng - refAng, 180)
                            # prove that nearAng and ang are the same angle
                            self.assertAlmostEqual(wrapCtr(nearAng - ang), 0)
                            self.assertAlmostEqual(sind(nearAng), sinAng)
                            self.assertAlmostEqual(cosd(nearAng), cosAng)
Exemple #2
0
    def testWrap(self):
        for wrap in (-1000, -10, -1, 0, 1, 10, 1000):
            for offset in (-360, -180, -90, 0, 90, 180, 270, 360):
                for epsMult in (-3, -2, -1, 0, 1, 2, 3):
                    ang = offset + (wrap * 360)
                    ang += ang * DoubleEpsilon * epsMult
                    sinAng = sind(ang)
                    cosAng = cosd(ang)
                    pvt = PVT(ang, ang, 35.0)  # pick anything for vel and time

                    posAng = wrapPos(ang)
                    self.assertGreaterEqual(posAng, 0.0)
                    self.assertLess(posAng, 360.0)
                    # prove that posAng and ang are the same angle
                    # sin and cos are a sanity check on wrapCtr
                    self.assertAlmostEqual(wrapCtr(posAng - ang), 0)
                    self.assertAlmostEqual(sind(posAng), sinAng)
                    self.assertAlmostEqual(cosd(posAng), cosAng)

                    posPvt = wrapPos(pvt)
                    self.assertEqual(posPvt.pos, posAng)
                    self.assertEqual(posPvt.vel, pvt.vel)
                    self.assertEqual(posPvt.t, pvt.t)

                    ctrAng = wrapCtr(ang)
                    self.assertGreaterEqual(ctrAng, -180.0)
                    self.assertLess(ctrAng, 180.0)
                    # prove that ctrAng and ang are the same angle
                    self.assertAlmostEqual(wrapCtr(ctrAng - ang), 0)
                    self.assertAlmostEqual(sind(ctrAng), sinAng)
                    self.assertAlmostEqual(cosd(ctrAng), cosAng)

                    ctrPvt = wrapCtr(pvt)
                    self.assertEqual(ctrPvt.pos, ctrAng)
                    self.assertEqual(ctrPvt.vel, pvt.vel)
                    self.assertEqual(ctrPvt.t, pvt.t)

                    for refAngBase in (-180, 0, 180, 360):
                        for refEpsMult in (-3, -2, -1, 0, 1, 2, 3):
                            refAng = refAngBase
                            refAng += refAng * refEpsMult * DoubleEpsilon
                            nearAng = wrapNear(ang, refAng)
                            self.assertGreaterEqual(nearAng - refAng, -180)
                            self.assertLess(nearAng - refAng, 180)
                            # prove that nearAng and ang are the same angle
                            self.assertAlmostEqual(wrapCtr(nearAng - ang), 0)
                            self.assertAlmostEqual(sind(nearAng), sinAng)
                            self.assertAlmostEqual(cosd(nearAng), cosAng)
def gmstFromUT1(ut1):
    """Convert from universal time (MJD)
    to Greenwich mean sidereal time, in degrees

    Based on Pat Wallace's GMST, whose comments follow:
    
    The IAU 1982 expression (see page S15 of 1984 Astronomical
    Almanac) is used, but rearranged to reduce rounding errors.
    This expression is always described as giving the GMST at
    0 hours UT.  In fact, it gives the difference between the
    GMST and the UT, which happens to equal the GMST (modulo
    24 hours) at 0 hours UT each day.  In this routine, the
    entire UT is used directly as the argument for the
    standard formula, and the fractional part of the UT is
    added separately;  note that the factor 1.0027379... does
    not appear.
    
    See also the routine GMSTA, which delivers better numerical
    precision by accepting the UT date and time as separate arguments.
    
    P.T.Wallace   Starlink   14 September 1995
    
    History:
    2002-20-12 ROwen    Removed an extra + sign that was doing nothing.
                        Thanks to pychecker.
    """
    # convert date to Julian centuries since J2000
    jc = (ut1 - coordConv.MJDJ2000) / 36525.0

    return coordConv.wrapPos(
        (math.fmod(ut1, 1.0) * 360.0)  # fraction of day of UT1, in degrees
        + (24110.54841 + (8640184.812866 +
                          (0.093104 -
                           (6.2e-6 * jc)) * jc) * jc) * 0.0041666666666666666)
def gmstFromUT1(ut1):
    """Convert from universal time (MJD)
    to Greenwich mean sidereal time, in degrees

    Based on Pat Wallace's GMST, whose comments follow:
    
    The IAU 1982 expression (see page S15 of 1984 Astronomical
    Almanac) is used, but rearranged to reduce rounding errors.
    This expression is always described as giving the GMST at
    0 hours UT.  In fact, it gives the difference between the
    GMST and the UT, which happens to equal the GMST (modulo
    24 hours) at 0 hours UT each day.  In this routine, the
    entire UT is used directly as the argument for the
    standard formula, and the fractional part of the UT is
    added separately;  note that the factor 1.0027379... does
    not appear.
    
    See also the routine GMSTA, which delivers better numerical
    precision by accepting the UT date and time as separate arguments.
    
    P.T.Wallace   Starlink   14 September 1995
    
    History:
    2002-20-12 ROwen    Removed an extra + sign that was doing nothing.
                        Thanks to pychecker.
    """
    # convert date to Julian centuries since J2000
    jc= (ut1 - coordConv.MJDJ2000) / 36525.0

    return coordConv.wrapPos (
        (math.fmod(ut1, 1.0) * 360.0) # fraction of day of UT1, in degrees
         + (24110.54841
            + (8640184.812866
               + (0.093104-(6.2e-6*jc))*jc)*jc)*0.0041666666666666666)
def lastFromTAI(tai, site):
    ut1Days = (tai + site.ut1_tai) / coordConv.SecPerDay
    gmst = gmstFromUT1(ut1Days)

    # compute apparent - mean sidereal time, in degrees
    ttDays = (tai + coordConv.TT_TAI) / coordConv.SecPerDay
    appMinusMean = eqeqx(ttDays) / coordConv.RadPerDeg

    # compute local apparent sideral time, in degrees, in range [0, 360)
    return coordConv.wrapPos(gmst + site.corrLong + appMinusMean)
def lastFromTAI(tai, site):
    ut1Days = (tai + site.ut1_tai) / coordConv.SecPerDay
    gmst = gmstFromUT1(ut1Days)

    # compute apparent - mean sidereal time, in degrees
    ttDays = (tai + coordConv.TT_TAI) / coordConv.SecPerDay;
    appMinusMean = eqeqx(ttDays) / coordConv.RadPerDeg;

    # compute local apparent sideral time, in degrees, in range [0, 360)
    return coordConv.wrapPos(gmst + site.corrLong + appMinusMean);
    def testBasics(self):
        """Check sph -> vec and back again for points not at the pole
        
        The round trip test relies on the fact that the internal representation of a coord is vector,
        so simply retrieving the sph info again suffices to test a round trip.
        
        Warning: the test of vector velocity is poor because the code is copied from the C++.
        However, two other tests will help:
        - Convert a coordinate system to itself with two different dates of observation
          and check that the expected amount of spatial motion occurs
        - Compare coordinate conversion results to the old TCC
        """
        for equatAng in (0, 71, -123.4):
            for polarAng in (0, -75, -89.999999, 89.999999):
                for parallax in (0, MinParallax / 0.9000001, MinParallax / 0.8999999, 5):
                    for equatPM in (4,): # (0, 4):
                        for polarPM in (-7,): # (0, -7):
                            for radVel in (0, -34):
                                coord = Coord(equatAng, polarAng, parallax, equatPM, polarPM, radVel)
                                self.assertFalse(coord.atPole())
                                self.assertEqual(coord.atInfinity(), parallax < MinParallax / 0.9)

                                # check vector position
                                vecPos = coord.getVecPos()
                                dist = coord.getDistance()
                                self.assertAlmostEqual(numpy.linalg.norm(vecPos), dist, 2)
                                predVecPos = (
                                    dist * cosd(polarAng) * cosd(equatAng),
                                    dist * cosd(polarAng) * sind(equatAng),
                                    dist * sind(polarAng),
                                )
                                self.assertTrue(numpy.allclose(predVecPos, vecPos))
                                
                                # check vector proper motion
                                vecPM = coord.getVecPM()
                                RadPerYear_per_ArcsecPerCentury = RadPerDeg / (ArcsecPerDeg * 100.0)
                                SecPerYear = SecPerDay * DaysPerYear
                                AUPerYear_per_KmPerSec = SecPerYear / KmPerAU

                                sinEquat = sind(equatAng)
                                cosEquat = cosd(equatAng)
                                sinPolar = sind(polarAng)
                                cosPolar = cosd(polarAng)

                                # change units of proper motion from arcsec/century to au/year
                                pmAUPerYear1 = equatPM * dist * RadPerYear_per_ArcsecPerCentury
                                pmAUPerYear2 = polarPM * dist * RadPerYear_per_ArcsecPerCentury

                                # change units of radial velocity from km/sec to au/year
                                radVelAUPerYear = radVel * AUPerYear_per_KmPerSec
                                
                                predVecPM = (
                                    - (pmAUPerYear2 * sinPolar * cosEquat) - (pmAUPerYear1 * cosPolar * sinEquat) + (radVelAUPerYear * cosPolar * cosEquat),
                                    - (pmAUPerYear2 * sinPolar * sinEquat) + (pmAUPerYear1 * cosPolar * cosEquat) + (radVelAUPerYear * cosPolar * sinEquat),
                                    + (pmAUPerYear2 * cosPolar)                                                   + (radVelAUPerYear * sinPolar),
                                )
                                self.assertTrue(numpy.allclose(predVecPM, vecPM))

                                # check round trip
                                atPole, destEquatAng, destPolarAng = coord.getSphPos()
                                self.assertAlmostEqual(wrapPos(equatAng), destEquatAng)
                                self.assertAlmostEqual(polarAng, destPolarAng)

                                destParallax = coord.getParallax()
                                predParallax = 0 if coord.atInfinity() else parallax
                                self.assertAlmostEqual(predParallax, destParallax)

                                atPole, destEquatPM, destPolarPM = coord.getPM()
                                self.assertAlmostEqual(equatPM, destEquatPM, 6)
                                self.assertAlmostEqual(polarPM, destPolarPM, 6)

                                destRadVel = coord.getRadVel()
                                self.assertAlmostEqual(radVel, destRadVel)
                                
                                coordCopy = Coord(coord)
                                self.assertEqual(repr(coord), repr(coordCopy))
Exemple #8
0
    def testBasics(self):
        """Check sph -> vec and back again for points not at the pole
        
        The round trip test relies on the fact that the internal representation of a coord is vector,
        so simply retrieving the sph info again suffices to test a round trip.
        
        Warning: the test of vector velocity is poor because the code is copied from the C++.
        However, two other tests will help:
        - Convert a coordinate system to itself with two different dates of observation
          and check that the expected amount of spatial motion occurs
        - Compare coordinate conversion results to the old TCC
        """
        for equatAng in (0, 71, -123.4):
            for polarAng in (0, -75, -89.999999, 89.999999):
                for parallax in (0, MinParallax / 0.9000001,
                                 MinParallax / 0.8999999, 5):
                    for equatPM in (4, ):  # (0, 4):
                        for polarPM in (-7, ):  # (0, -7):
                            for radVel in (0, -34):
                                coord = Coord(equatAng, polarAng, parallax,
                                              equatPM, polarPM, radVel)
                                self.assertFalse(coord.atPole())
                                self.assertEqual(coord.atInfinity(),
                                                 parallax < MinParallax / 0.9)

                                # check vector position
                                vecPos = coord.getVecPos()
                                dist = coord.getDistance()
                                self.assertAlmostEqual(
                                    numpy.linalg.norm(vecPos), dist, 2)
                                predVecPos = (
                                    dist * cosd(polarAng) * cosd(equatAng),
                                    dist * cosd(polarAng) * sind(equatAng),
                                    dist * sind(polarAng),
                                )
                                self.assertTrue(
                                    numpy.allclose(predVecPos, vecPos))

                                # check vector proper motion
                                vecPM = coord.getVecPM()
                                RadPerYear_per_ArcsecPerCentury = RadPerDeg / (
                                    ArcsecPerDeg * 100.0)
                                SecPerYear = SecPerDay * DaysPerYear
                                AUPerYear_per_KmPerSec = SecPerYear / KmPerAU

                                sinEquat = sind(equatAng)
                                cosEquat = cosd(equatAng)
                                sinPolar = sind(polarAng)
                                cosPolar = cosd(polarAng)

                                # change units of proper motion from arcsec/century to au/year
                                pmAUPerYear1 = equatPM * dist * RadPerYear_per_ArcsecPerCentury
                                pmAUPerYear2 = polarPM * dist * RadPerYear_per_ArcsecPerCentury

                                # change units of radial velocity from km/sec to au/year
                                radVelAUPerYear = radVel * AUPerYear_per_KmPerSec

                                predVecPM = (
                                    -(pmAUPerYear2 * sinPolar * cosEquat) -
                                    (pmAUPerYear1 * cosPolar * sinEquat) +
                                    (radVelAUPerYear * cosPolar * cosEquat),
                                    -(pmAUPerYear2 * sinPolar * sinEquat) +
                                    (pmAUPerYear1 * cosPolar * cosEquat) +
                                    (radVelAUPerYear * cosPolar * sinEquat),
                                    +(pmAUPerYear2 * cosPolar) +
                                    (radVelAUPerYear * sinPolar),
                                )
                                self.assertTrue(
                                    numpy.allclose(predVecPM, vecPM))

                                # check round trip
                                atPole, destEquatAng, destPolarAng = coord.getSphPos(
                                )
                                self.assertAlmostEqual(wrapPos(equatAng),
                                                       destEquatAng)
                                self.assertAlmostEqual(polarAng, destPolarAng)

                                destParallax = coord.getParallax()
                                predParallax = 0 if coord.atInfinity(
                                ) else parallax
                                self.assertAlmostEqual(predParallax,
                                                       destParallax)

                                atPole, destEquatPM, destPolarPM = coord.getPM(
                                )
                                self.assertAlmostEqual(equatPM, destEquatPM, 6)
                                self.assertAlmostEqual(polarPM, destPolarPM, 6)

                                destRadVel = coord.getRadVel()
                                self.assertAlmostEqual(radVel, destRadVel)

                                coordCopy = Coord(coord)
                                self.assertEqual(repr(coord), repr(coordCopy))