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
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
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
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
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