def observed_to_cirs(observed_coo, cirs_frame): usrepr = observed_coo.represent_as(UnitSphericalRepresentation) lon = usrepr.lon.to_value(u.radian) lat = usrepr.lat.to_value(u.radian) if isinstance(observed_coo, AltAz): # the 'A' indicates zen/az inputs coord_type = 'A' lat = PIOVER2 - lat else: coord_type = 'H' # first set up the astrometry context for ICRS<->CIRS at the observed_coo time astrom = erfa_astrom.get().apio(observed_coo) cirs_ra, cirs_dec = erfa.atoiq(coord_type, lon, lat, astrom) << u.radian if isinstance(observed_coo.data, UnitSphericalRepresentation) or observed_coo.cartesian.x.unit == u.one: distance = None else: distance = observed_coo.distance cirs_at_aa_time = CIRS(ra=cirs_ra, dec=cirs_dec, distance=distance, obstime=observed_coo.obstime, location=observed_coo.location) # this final transform may be a no-op if the obstimes and locations are the same return cirs_at_aa_time.transform_to(cirs_frame)
def altaz_to_cirs(altaz_coo, cirs_frame): usrepr = altaz_coo.represent_as(UnitSphericalRepresentation) az = usrepr.lon.to_value(u.radian) zen = PIOVER2 - usrepr.lat.to_value(u.radian) # first set up the astrometry context for ICRS<->CIRS at the altaz_coo time astrom = erfa_astrom.get().apio13(altaz_coo) # the 'A' indicates zen/az inputs cirs_ra, cirs_dec = erfa.atoiq('A', az, zen, astrom) * u.radian if isinstance(altaz_coo.data, UnitSphericalRepresentation ) or altaz_coo.cartesian.x.unit == u.one: cirs_at_aa_time = CIRS(ra=cirs_ra, dec=cirs_dec, distance=None, obstime=altaz_coo.obstime) else: # treat the output of atoiq as an "astrometric" RA/DEC, so to get the # actual RA/Dec from the observers vantage point, we have to reverse # the vector operation of cirs_to_altaz (see there for more detail) loccirs = altaz_coo.location.get_itrs( altaz_coo.obstime).transform_to(cirs_frame) astrometric_rep = SphericalRepresentation(lon=cirs_ra, lat=cirs_dec, distance=altaz_coo.distance) newrepr = astrometric_rep + loccirs.cartesian cirs_at_aa_time = CIRS(newrepr, obstime=altaz_coo.obstime) # this final transform may be a no-op if the obstimes are the same return cirs_at_aa_time.transform_to(cirs_frame)
def _erfa_check(ira, idec, astrom): """ This function does the same thing the astropy layer is supposed to do, but all in erfa """ cra, cdec = erfa.atciq(ira, idec, 0, 0, 0, 0, astrom) az, zen, ha, odec, ora = erfa.atioq(cra, cdec, astrom) alt = np.pi / 2 - zen cra2, cdec2 = erfa.atoiq('A', az, zen, astrom) ira2, idec2 = erfa.aticq(cra2, cdec2, astrom) dct = locals() del dct['astrom'] return dct
def altaz_to_cirs(altaz_coo, cirs_frame): usrepr = altaz_coo.represent_as(UnitSphericalRepresentation) az = usrepr.lon.to_value(u.radian) zen = PIOVER2 - usrepr.lat.to_value(u.radian) lon, lat, height = altaz_coo.location.to_geodetic('WGS84') xp, yp = get_polar_motion(altaz_coo.obstime) # first set up the astrometry context for ICRS<->CIRS at the altaz_coo time jd1, jd2 = get_jd12(altaz_coo.obstime, 'utc') astrom = erfa.apio13( jd1, jd2, get_dut1utc(altaz_coo.obstime), lon.to_value(u.radian), lat.to_value(u.radian), height.to_value(u.m), xp, yp, # polar motion # all below are already in correct units because they are QuantityFrameAttribues altaz_coo.pressure.value, altaz_coo.temperature.value, altaz_coo.relative_humidity.value, altaz_coo.obswl.value) # the 'A' indicates zen/az inputs cirs_ra, cirs_dec = erfa.atoiq('A', az, zen, astrom) * u.radian if isinstance(altaz_coo.data, UnitSphericalRepresentation ) or altaz_coo.cartesian.x.unit == u.one: cirs_at_aa_time = CIRS(ra=cirs_ra, dec=cirs_dec, distance=None, obstime=altaz_coo.obstime) else: # treat the output of atoiq as an "astrometric" RA/DEC, so to get the # actual RA/Dec from the observers vantage point, we have to reverse # the vector operation of cirs_to_altaz (see there for more detail) loccirs = altaz_coo.location.get_itrs( altaz_coo.obstime).transform_to(cirs_frame) astrometric_rep = SphericalRepresentation(lon=cirs_ra, lat=cirs_dec, distance=altaz_coo.distance) newrepr = astrometric_rep + loccirs.cartesian cirs_at_aa_time = CIRS(newrepr, obstime=altaz_coo.obstime) # this final transform may be a no-op if the obstimes are the same return cirs_at_aa_time.transform_to(cirs_frame)
def observed_to_icrs(observed_coo, icrs_frame): # if the data are UnitSphericalRepresentation, we can skip the distance calculations is_unitspherical = (isinstance(observed_coo.data, UnitSphericalRepresentation) or observed_coo.cartesian.x.unit == u.one) usrepr = observed_coo.represent_as(UnitSphericalRepresentation) lon = usrepr.lon.to_value(u.radian) lat = usrepr.lat.to_value(u.radian) if isinstance(observed_coo, AltAz): # the 'A' indicates zen/az inputs coord_type = 'A' lat = PIOVER2 - lat else: coord_type = 'H' # first set up the astrometry context for ICRS<->CIRS at the observed_coo time astrom = erfa_astrom.get().apco(observed_coo) # Topocentric CIRS cirs_ra, cirs_dec = erfa.atoiq(coord_type, lon, lat, astrom) << u.radian if is_unitspherical: srepr = SphericalRepresentation(cirs_ra, cirs_dec, 1, copy=False) else: srepr = SphericalRepresentation(lon=cirs_ra, lat=cirs_dec, distance=observed_coo.distance, copy=False) # BCRS (Astrometric) direction to source bcrs_ra, bcrs_dec = aticq(srepr, astrom) << u.radian # Correct for parallax to get ICRS representation if is_unitspherical: icrs_srepr = UnitSphericalRepresentation(bcrs_ra, bcrs_dec, copy=False) else: icrs_srepr = SphericalRepresentation(lon=bcrs_ra, lat=bcrs_dec, distance=observed_coo.distance, copy=False) observer_icrs = CartesianRepresentation(astrom['eb'], unit=u.au, xyz_axis=-1, copy=False) newrepr = icrs_srepr.to_cartesian() + observer_icrs icrs_srepr = newrepr.represent_as(SphericalRepresentation) return icrs_frame.realize_frame(icrs_srepr)
def altaz_to_cirs(altaz_coo, cirs_frame): usrepr = altaz_coo.represent_as(UnitSphericalRepresentation) az = usrepr.lon.to_value(u.radian) zen = PIOVER2 - usrepr.lat.to_value(u.radian) # first set up the astrometry context for ICRS<->CIRS at the altaz_coo time astrom = erfa_astrom.get().apio(altaz_coo) # the 'A' indicates zen/az inputs cirs_ra, cirs_dec = erfa.atoiq('A', az, zen, astrom) << u.radian if isinstance(altaz_coo.data, UnitSphericalRepresentation ) or altaz_coo.cartesian.x.unit == u.one: distance = None else: distance = altaz_coo.distance cirs_at_aa_time = CIRS(ra=cirs_ra, dec=cirs_dec, distance=distance, obstime=altaz_coo.obstime, location=altaz_coo.location) # this final transform may be a no-op if the obstimes and locations are the same return cirs_at_aa_time.transform_to(cirs_frame)