def cirs_to_altaz(cirs_coo, altaz_frame): if np.any(cirs_coo.obstime != altaz_frame.obstime): # the only frame attribute for the current CIRS is the obstime, but this # would need to be updated if a future change allowed specifying an # Earth location algorithm or something cirs_coo = cirs_coo.transform_to(CIRS(obstime=altaz_frame.obstime)) # we use the same obstime everywhere now that we know they're the same obstime = cirs_coo.obstime # if the data are UnitSphericalRepresentation, we can skip the distance calculations is_unitspherical = (isinstance(cirs_coo.data, UnitSphericalRepresentation) or cirs_coo.cartesian.x.unit == u.one) if is_unitspherical: usrepr = cirs_coo.represent_as(UnitSphericalRepresentation) cirs_ra = usrepr.lon.to_value(u.radian) cirs_dec = usrepr.lat.to_value(u.radian) else: # compute an "astrometric" ra/dec -i.e., the direction of the # displacement vector from the observer to the target in CIRS loccirs = altaz_frame.location.get_itrs(cirs_coo.obstime).transform_to(cirs_coo) diffrepr = (cirs_coo.cartesian - loccirs.cartesian).represent_as(UnitSphericalRepresentation) cirs_ra = diffrepr.lon.to_value(u.radian) cirs_dec = diffrepr.lat.to_value(u.radian) lon, lat, height = altaz_frame.location.to_geodetic('WGS84') xp, yp = get_polar_motion(obstime) # first set up the astrometry context for CIRS<->AltAz jd1, jd2 = get_jd12(obstime, 'utc') astrom = erfa.apio13(jd1, jd2, get_dut1utc(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_frame.pressure.value, altaz_frame.temperature.value, altaz_frame.relative_humidity.value, altaz_frame.obswl.value) az, zen, _, _, _ = erfa.atioq(cirs_ra, cirs_dec, astrom) if is_unitspherical: rep = UnitSphericalRepresentation(lat=u.Quantity(PIOVER2 - zen, u.radian, copy=False), lon=u.Quantity(az, u.radian, copy=False), copy=False) else: # now we get the distance as the cartesian distance from the earth # location to the coordinate location locitrs = altaz_frame.location.get_itrs(obstime) distance = locitrs.separation_3d(cirs_coo) rep = SphericalRepresentation(lat=u.Quantity(PIOVER2 - zen, u.radian, copy=False), lon=u.Quantity(az, u.radian, copy=False), distance=distance, copy=False) return altaz_frame.realize_frame(rep)
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 _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 cirs_to_altaz(cirs_coo, altaz_frame): if np.any(cirs_coo.obstime != altaz_frame.obstime): # the only frame attribute for the current CIRS is the obstime, but this # would need to be updated if a future change allowed specifying an # Earth location algorithm or something cirs_coo = cirs_coo.transform_to(CIRS(obstime=altaz_frame.obstime)) # we use the same obstime everywhere now that we know they're the same obstime = cirs_coo.obstime # if the data are UnitSphericalRepresentation, we can skip the distance calculations is_unitspherical = (isinstance(cirs_coo.data, UnitSphericalRepresentation) or cirs_coo.cartesian.x.unit == u.one) if is_unitspherical: usrepr = cirs_coo.represent_as(UnitSphericalRepresentation) cirs_ra = usrepr.lon.to_value(u.radian) cirs_dec = usrepr.lat.to_value(u.radian) else: # compute an "astrometric" ra/dec -i.e., the direction of the # displacement vector from the observer to the target in CIRS loccirs = altaz_frame.location.get_itrs( cirs_coo.obstime).transform_to(cirs_coo) diffrepr = ( cirs_coo.cartesian - loccirs.cartesian).represent_as(UnitSphericalRepresentation) cirs_ra = diffrepr.lon.to_value(u.radian) cirs_dec = diffrepr.lat.to_value(u.radian) lon, lat, height = altaz_frame.location.to_geodetic('WGS84') xp, yp = get_polar_motion(obstime) # first set up the astrometry context for CIRS<->AltAz jd1, jd2 = get_jd12(obstime, 'utc') astrom = erfa.apio13( jd1, jd2, get_dut1utc(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_frame.pressure.value, altaz_frame.temperature.value, altaz_frame.relative_humidity.value, altaz_frame.obswl.value) az, zen, _, _, _ = erfa.atioq(cirs_ra, cirs_dec, astrom) if is_unitspherical: rep = UnitSphericalRepresentation(lat=u.Quantity(PIOVER2 - zen, u.radian, copy=False), lon=u.Quantity(az, u.radian, copy=False), copy=False) else: # now we get the distance as the cartesian distance from the earth # location to the coordinate location locitrs = altaz_frame.location.get_itrs(obstime) distance = locitrs.separation_3d(cirs_coo) rep = SphericalRepresentation(lat=u.Quantity(PIOVER2 - zen, u.radian, copy=False), lon=u.Quantity(az, u.radian, copy=False), distance=distance, copy=False) return altaz_frame.realize_frame(rep)