Source code for realtime.receive.core.katpoint_uvw_engine

import katpoint
import numpy as np
from astropy import units as u
from astropy.coordinates import Angle, CartesianRepresentation, EarthLocation
from astropy.time import Time

from .uvw_engine import UVWEngine


[docs] class KatpointUVWEngine(UVWEngine): """ A derived class that uses katpoint to determine the UVW of the antennas. One complication is that katpoint prefers topocentric antenna reference positions. You may not that the UVWEngine creates a geocentric antenna UVW so all baselines can be generated by subtractions. This will need another reference position """ # building an antenna at the centre of the Earth geo_location = EarthLocation.from_geocentric(0.0 * u.m, 0.0 * u.m, 0.0 * u.m) ref_longitude, ref_latitude, ref_height = geo_location.to_geodetic(ellipsoid="WGS84") # pylint: disable=consider-using-f-string desc = "GEOCENTRE,{lat},{long},{ht},12.0,0,0,0,0)".format( lat=ref_latitude.to_string(sep=":"), long=ref_longitude.to_string(sep=":"), ht=ref_height.value, ) geo_antenna = katpoint.Antenna(desc)
[docs] @staticmethod def get_antenna_uvw( antenna_location: np.array, epoch: Time, ra: Angle, dec: Angle, position_frame="itrf", epoch_frame="icrs", swap_baselines=False, ) -> np.ndarray: """ Internal class that uses the Engine to determine the UVW This is specific to the Katpoint engine. This must have a reference position. For the basic engine this is the geocentre - so we replicate it here This overloads a more general method. There are some fixed assumptions here: The position is geocentric (in metres) The RA and DEC are ICRS :param list antenna_location: position of the antenna (vector geocentric XYZ in m) :param astropy.Time epoch: Time for which to calculate the UVW :param astropy.Angle ra: Right Ascension (ICRS) :param astropy.Angle dec: Declination (ICRS) :param str position_frame: The frame of the input positions (currently assumes geocentric itrf) :param str epoch_frame: NOT USED. :param Bool swap_baselines: NOT USED. :returns: The geocentric UVW baseline :rtype: numpy.ndarray [u,v,w] """ # We need to set up the target direction tgt_katpoint = katpoint.construct_radec_target(ra.rad, dec.rad) # We also need a timestamp # In the katpoint docs an astropy.Time object is supposed to work # but it doesn't seem to. # This seems to be related to the katpoint version and 1.0 is more reliable # still getting issues due to the possibiltiy of epoch being a sequence # of some sort but @rtobar introduced me to numpy.squeeze # epoch.format = "iso" # desc = "{t}".format(t=epoch[0]) # # or # # if hasattr(epoch,"__len__"): # epoch = epoch[0] # # or neater epoch = np.squeeze(epoch) timestamp = katpoint.Timestamp(epoch) # we need the antenna location in katpoint format ant1_location = EarthLocation.from_geocentric( antenna_location[0] * u.m, antenna_location[1] * u.m, antenna_location[2] * u.m, ) # the constructor wants a geodetic longitude, latitude, height = ant1_location.to_geodetic(ellipsoid="WGS84") # pylint: disable=consider-using-f-string desc = "a1,{lat},{long},{ht},12.0,0,0,0,0)".format( lat=latitude.to_string(sep=":"), long=longitude.to_string(sep=":"), ht=height.value, ) ant = katpoint.Antenna(desc) # Now we have all we need # This evaluates the UVW <at> the location od ant in the direction of geo_ant. uvw = tgt_katpoint.uvw(ant, timestamp, KatpointUVWEngine.geo_antenna) # the inversion is becuase I want the baseline to point from CoM to the # antenna. if isinstance(uvw, CartesianRepresentation): return (np.array(uvw.get_xyz())).squeeze() else: return np.array(uvw)