def apci(self, frame_or_coord): ''' Wrapper for ``erfa.apci``, used in conversions CIRS <-> ICRS Arguments --------- frame_or_coord: ``astropy.coordinates.BaseCoordinateFrame`` or ``astropy.coordinates.SkyCoord`` Frame or coordinate instance in the corresponding frame for which to calculate the calculate the astrom values. For this function, a CIRS frame is expected. ''' obstime = frame_or_coord.obstime # no point in interpolating for a single value if obstime.size == 1: return super().apci(frame_or_coord) support = self._get_support_points(obstime) cip = self._get_cip(support, obstime) earth_pv, earth_heliocentric = self._prepare_earth_position_vel( support, obstime) jd1_tt, jd2_tt = get_jd12(obstime, 'tt') astrom = erfa.apci(jd1_tt, jd2_tt, earth_pv, earth_heliocentric, *cip) return astrom
def icrs_to_cirs(icrs_coo, cirs_frame): # first set up the astrometry context for ICRS<->CIRS jd1, jd2 = get_jd12(cirs_frame.obstime, 'tt') x, y, s = get_cip(jd1, jd2) earth_pv, earth_heliocentric = prepare_earth_position_vel( cirs_frame.obstime) # erfa.apci requests TDB but TT can be used instead of TDB without any significant impact on accuracy astrom = erfa.apci(jd1, jd2, earth_pv, earth_heliocentric, x, y, s) if icrs_coo.data.get_name( ) == 'unitspherical' or icrs_coo.data.to_cartesian().x.unit == u.one: # if no distance, just do the infinite-distance/no parallax calculation usrepr = icrs_coo.represent_as(UnitSphericalRepresentation) i_ra = usrepr.lon.to_value(u.radian) i_dec = usrepr.lat.to_value(u.radian) cirs_ra, cirs_dec = atciqz(i_ra, i_dec, astrom) newrep = UnitSphericalRepresentation(lat=u.Quantity(cirs_dec, u.radian, copy=False), lon=u.Quantity(cirs_ra, u.radian, copy=False), copy=False) else: # When there is a distance, we first offset for parallax to get the # astrometric coordinate direction and *then* run the ERFA transform for # no parallax/PM. This ensures reversibility and is more sensible for # inside solar system objects astrom_eb = CartesianRepresentation(astrom['eb'], unit=u.au, xyz_axis=-1, copy=False) newcart = icrs_coo.cartesian - astrom_eb srepr = newcart.represent_as(SphericalRepresentation) i_ra = srepr.lon.to_value(u.radian) i_dec = srepr.lat.to_value(u.radian) cirs_ra, cirs_dec = atciqz(i_ra, i_dec, astrom) newrep = SphericalRepresentation(lat=u.Quantity(cirs_dec, u.radian, copy=False), lon=u.Quantity(cirs_ra, u.radian, copy=False), distance=srepr.distance, copy=False) return cirs_frame.realize_frame(newrep)
def apci(frame_or_coord): ''' Wrapper for ``erfa.apci``, used in conversions CIRS <-> ICRS Arguments --------- frame_or_coord: ``astropy.coordinates.BaseCoordinateFrame`` or ``astropy.coordinates.SkyCoord`` Frame or coordinate instance in the corresponding frame for which to calculate the calculate the astrom values. For this function, a CIRS frame is expected. ''' jd1_tt, jd2_tt = get_jd12(frame_or_coord.obstime, 'tt') cip = get_cip(jd1_tt, jd2_tt) earth_pv, earth_heliocentric = prepare_earth_position_vel( frame_or_coord.obstime) return erfa.apci(jd1_tt, jd2_tt, earth_pv, earth_heliocentric, *cip)
def cirs_to_icrs(cirs_coo, icrs_frame): srepr = cirs_coo.represent_as(SphericalRepresentation) cirs_ra = srepr.lon.to_value(u.radian) cirs_dec = srepr.lat.to_value(u.radian) # set up the astrometry context for ICRS<->cirs and then convert to # astrometric coordinate direction jd1, jd2 = get_jd12(cirs_coo.obstime, 'tt') x, y, s = get_cip(jd1, jd2) earth_pv, earth_heliocentric = prepare_earth_position_vel(cirs_coo.obstime) # erfa.apci requests TDB but TT can be used instead of TDB without any significant impact on accuracy astrom = erfa.apci(jd1, jd2, earth_pv, earth_heliocentric, x, y, s) i_ra, i_dec = aticq(cirs_ra, cirs_dec, astrom) if cirs_coo.data.get_name( ) == 'unitspherical' or cirs_coo.data.to_cartesian().x.unit == u.one: # if no distance, just use the coordinate direction to yield the # infinite-distance/no parallax answer newrep = UnitSphericalRepresentation(lat=u.Quantity(i_dec, u.radian, copy=False), lon=u.Quantity(i_ra, u.radian, copy=False), copy=False) else: # When there is a distance, apply the parallax/offset to the SSB as the # last step - ensures round-tripping with the icrs_to_cirs transform # the distance in intermedrep is *not* a real distance as it does not # include the offset back to the SSB intermedrep = SphericalRepresentation(lat=u.Quantity(i_dec, u.radian, copy=False), lon=u.Quantity(i_ra, u.radian, copy=False), distance=srepr.distance, copy=False) astrom_eb = CartesianRepresentation(astrom['eb'], unit=u.au, xyz_axis=-1, copy=False) newrep = intermedrep + astrom_eb return icrs_frame.realize_frame(newrep)
) ] ) # era 2000A CIP. r = erfa.pnm00a(tt1, tt2) x, y = erfa.bpn2xy(r) # Apply IERS corrections. x += dx y += dy # SOFA CIO locator. */ s = erfa.s06(tt1, tt2, x, y) # Populate the context. astrom = erfa.apci(tt1, tt2, pvb, pvh, x, y, s) # Carry out the transformation and report the results. ri, di = erfa.atciq(rc, dc, pr, pd, px, rv, astrom) reprd("ICRS -> CIRS (JPL, IERS):", ri, di) # The same but with Saturn then Jupiter then Sun light deflection. b0 = erfa.LDBODY( ( 0.00028574, 3e-10, np.array( ( (-7.8101442680818964, -5.6095668114887358, -1.9807981923749924), (0.0030723248971152, -0.0040699547707598, -0.0018133584165345), )
# JPL DE405 barycentric Earth ephemeris. pvb = ((-0.9741704366519668, -0.2115201000882231, -0.0917583114068277), (0.0036436589347388, -0.0154287318503146, -0.0066892203821059)) # era 2000A CIP. r = erfa.pnm00a(tt1, tt2) x, y = erfa.bpn2xy(r) # Apply IERS corrections. x += dx y += dy # SOFA CIO locator. */ s = erfa.s06(tt1, tt2, x, y) # Populate the context. astrom = erfa.apci(tt1, tt2, pvb, pvh[0], x, y, s) # Carry out the transformation and report the results. ri, di = erfa.atciq(rc, dc, pr, pd, px, rv, *astrom) reprd("ICRS -> CIRS (JPL, IERS):", ri, di) # The same but with Saturn then Jupiter then Sun light deflection. b0 = erfa.LDBODY( (0.00028574, 3e-10, ((-7.8101442680818964, -5.6095668114887358, -1.9807981923749924), (0.0030723248971152, -0.0040699547707598, -0.0018133584165345)))) b1 = erfa.LDBODY( (0.00095435, 3e-9, ((0.7380987962351833, .6365869247538951, 1.9693136030111202), (-0.0075581692172088, 0.0012691372216750, 0.0007279990012801)))) b2 = erfa.LDBODY(