예제 #1
0
    def _get_ut1_from_utc(cls, UTC):
        """
        Take a numpy array of UTC values and return a numpy array of UT1 and dut1 values
        """

        time_list = Time(UTC, scale='utc', format='mjd')

        try:
            dut1_out = time_list.delta_ut1_utc
            ut1_out = time_list.ut1.mjd
        except IERSRangeError:
            ut1_out = np.copy(UTC)
            dut1_out = np.zeros(len(UTC))
            warnings.warn("ModifiedJulianData.get_list() was given date values that are outside "
                          "astropy's range of interpolation for converting from UTC to UT1. "
                          "We will treat UT1=UTC for those dates, lacking a better alternative.",
                          category=UTCtoUT1Warning)
            from astropy.utils.iers import TIME_BEFORE_IERS_RANGE, TIME_BEYOND_IERS_RANGE
            dut1_test, status = time_list.get_delta_ut1_utc(return_status=True)
            good_dexes = np.where(np.logical_and(status != TIME_BEFORE_IERS_RANGE,
                                                 status != TIME_BEYOND_IERS_RANGE))

            if len(good_dexes[0]) > 0:
                time_good = Time(UTC[good_dexes], scale='utc', format='mjd')
                dut1_good = time_good.delta_ut1_utc
                ut1_good = time_good.ut1.mjd

                ut1_out[good_dexes] = ut1_good
                dut1_out[good_dexes] = dut1_good

        return ut1_out, dut1_out
예제 #2
0
def iod_obs_tod(location: EarthLocation, epoch: Time):
    """
    Get the true of date (tod) position-velocity vector of the observatory

    Parameters
    ----------
    location: `~astropy.coordinates.EarthLocation`
        Position vector in body fixed reference frame.
    epoch: `~astropy.time.Time`

    Returns
    -------
    pos, vel: ~astropy.units.Quantity
        Position and velocity vector of the observation, in tod frame

    """
    from astropy.coordinates.earth import OMEGA_EARTH
    from astropy import _erfa as erfa
    assert isinstance(location, EarthLocation)
    assert isinstance(epoch, Time)

    dut = epoch.get_delta_ut1_utc(iers_table=iers_table)
    ut1 = Time(epoch.mjd + dut.to_value('day'), format='mjd', scale='ut1')
    earth_rotation_angle = erfa.era00(ut1.jd1, ut1.jd2) * u.rad
    loc = location.get_itrs()
    unit = loc.x.unit
    loc = np.array([loc.x.value, loc.y.value, loc.z.value])
    pos = np.matmul(rotation_matrix(-earth_rotation_angle, 'z'), loc)
    vel = [-OMEGA_EARTH.value * pos[1], OMEGA_EARTH.value * pos[0], 0.0]
    acc = [-OMEGA_EARTH.value**2 * pos[0], -OMEGA_EARTH.value**2 * pos[1], 0.0]

    return pos * unit, \
           vel * unit * OMEGA_EARTH.unit, \
           acc * unit * OMEGA_EARTH.unit * OMEGA_EARTH.unit
예제 #3
0
def examine_exposure(info, cframe, cframe_keys):
    # Process CFrame header keywords
    for keyword in cframe_keys:
        info[keyword] = cframe.header[keyword]

    obs_ra = cframe.header['RADEG']
    obs_dec = cframe.header['DECDEG']
    taibeg = cframe.header['TAI-BEG']
    taiend = cframe.header['TAI-END']

    taimid = 0.5*(taibeg+taiend)
    dec = Angle(obs_dec, u.degree)
    ra = Angle(obs_ra, u.degree)



    time = Time(taimid/86400.0, format='mjd', scale='tai', location=apo)
    try:
        lst = time.sidereal_time('apparent')
    except IndexError:
        ## workaround for problem with recent observations relative to astropy release
        ## http://astropy.readthedocs.org/en/v0.4.2/time/index.html#transformation-offsets
        from astropy.utils.iers import IERS_A, IERS_A_URL
        from astropy.utils.data import download_file 
        iers_a_file = download_file(IERS_A_URL, cache=True)  
        iers_a = IERS_A.open(iers_a_file)                     
        time.delta_ut1_utc = time.get_delta_ut1_utc(iers_a)

        lst = time.sidereal_time('apparent')

    ha = (lst - ra)

    if ha > np.pi*u.radian:
        ha -= 2*np.pi*u.radian
    elif ha < -np.pi*u.radian:
        ha += 2*np.pi*u.radian
    info['mean_ha'] = ha.to(u.degree).value

    alt, az = equatorial_to_horizontal(ra, dec, apolat, ha)
    info['mean_alt'] = alt.to(u.degree).value
예제 #4
0
def examine_exposure(info, cframe, cframe_keys):
    # Process CFrame header keywords
    for keyword in cframe_keys:
        info[keyword] = cframe.header[keyword]

    obs_ra = cframe.header['RADEG']
    obs_dec = cframe.header['DECDEG']
    taibeg = cframe.header['TAI-BEG']
    taiend = cframe.header['TAI-END']

    taimid = 0.5 * (taibeg + taiend)
    dec = Angle(obs_dec, u.degree)
    ra = Angle(obs_ra, u.degree)

    time = Time(taimid / 86400.0, format='mjd', scale='tai', location=apo)
    try:
        lst = time.sidereal_time('apparent')
    except IndexError:
        ## workaround for problem with recent observations relative to astropy release
        ## http://astropy.readthedocs.org/en/v0.4.2/time/index.html#transformation-offsets
        from astropy.utils.iers import IERS_A, IERS_A_URL
        from astropy.utils.data import download_file
        iers_a_file = download_file(IERS_A_URL, cache=True)
        iers_a = IERS_A.open(iers_a_file)
        time.delta_ut1_utc = time.get_delta_ut1_utc(iers_a)

        lst = time.sidereal_time('apparent')

    ha = (lst - ra)

    if ha > np.pi * u.radian:
        ha -= 2 * np.pi * u.radian
    elif ha < -np.pi * u.radian:
        ha += 2 * np.pi * u.radian
    info['mean_ha'] = ha.to(u.degree).value

    alt, az = equatorial_to_horizontal(ra, dec, apolat, ha)
    info['mean_alt'] = alt.to(u.degree).value
예제 #5
0
def get_lst_for_time(jd_array, latitude, longitude, altitude):
    """
    Get the lsts for a set of jd times at an earth location.

    Args:
        jd_array: an array of JD times to get lst for
        latitude: latitude of location to get lst for in degrees
        longitude: longitude of location to get lst for in degrees
        altitude: altitude of location to get lst for in meters

    Returns:
        an array of lst times corresponding to the jd_array
    """
    lsts = []
    lst_array = np.zeros_like(jd_array)
    for ind, jd in enumerate(np.unique(jd_array)):
        t = Time(jd,
                 format='jd',
                 location=(Angle(longitude,
                                 unit='deg'), Angle(latitude, unit='deg')))

        # avoid errors if iers.conf.auto_max_age is set to None, as we do in testing if the iers url is down
        if iers.conf.auto_max_age is None:  # pragma: no cover
            delta, status = t.get_delta_ut1_utc(return_status=True)
            if ((status == iers.TIME_BEFORE_IERS_RANGE)
                    or (status == iers.TIME_BEYOND_IERS_RANGE)):
                warnings.warn(
                    'time is out of IERS range, setting delta ut1 utc to extrapolated value'
                )
                t.delta_ut1_utc = delta

        lst_array[np.where(
            np.isclose(jd, jd_array, atol=1e-6,
                       rtol=1e-12))] = t.sidereal_time('apparent').radian

    return lst_array
class ModifiedJulianDate(object):


    def __init__(self, TAI=None, UTC=None):
        """
        Must specify either:

        @param [in] TAI = the International Atomic Time as an MJD

        or

        @param [in] UTC = Universal Coordinate Time as an MJD
        """

        if TAI is None and UTC is None:
            raise RuntimeError("You must specify either TAI or UTC to "
                               "instantiate ModifiedJulianDate")

        if TAI is not None:
            self._time = Time(TAI, scale='tai', format='mjd')
            self._tai = TAI
            self._utc = None
        else:
            self._time = Time(UTC, scale='utc', format='mjd')
            self._utc = UTC
            self._tai = None

        self._tt = None
        self._tdb = None
        self._ut1 = None
        self._dut1 = None


    def __eq__(self, other):
        return self._time == other._time


    @property
    def TAI(self):
        """
        International Atomic Time as an MJD
        """
        if self._tai is None:
            self._tai = self._time.tai.mjd

        return self._tai


    @property
    def UTC(self):
        """
        Universal Coordinate Time as an MJD
        """
        if self._utc is None:
            self._utc = self._time.utc.mjd

        return self._utc



    @property
    def UT1(self):
        """
        Universal Time as an MJD
        """
        if self._ut1 is None:
            try:
                self._ut1 = self._time.ut1.mjd
            except:
                warnings.warn("UTC %e is outside of IERS table for UT1-UTC.\n" % self.UTC
                              + "Returning UT1 = UTC for lack of a better idea")
                self._ut1 = self.UTC

        return self._ut1


    @property
    def dut1(self):
        """
        UT1-UTC in seconds
        """

        if self._dut1 is None:
            try:
                intermediate_value = self._time.get_delta_ut1_utc()
                try:
                    self._dut1 = intermediate_value.value
                except:
                    self._dut1 = intermediate_value
            except:
                warnings.warn("UTC %e is outside of IERS table for UT1-UTC.\n" % self.UTC
                              + "Returning UT1 = UTC for lack of a better idea")
                self._dut1 = 0.0

        return self._dut1


    @property
    def TT(self):
        """
        Terrestrial Time (aka Terrestrial Dynamical Time) as an MJD
        """
        if self._tt is None:
            self._tt = self._time.tt.mjd

        return self._tt


    @property
    def TDB(self):
        """
        Barycentric Dynamical Time as an MJD
        """
        if self._tdb is None:
            self._tdb = self._time.tdb.mjd

        return self._tdb