Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add optional near-field corrections to the phasing function #1482

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 123 additions & 1 deletion src/pyuvdata/utils/phasing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
import erfa
import numpy as np
from astropy import units
from astropy.coordinates import Angle, Distance, EarthLocation, SkyCoord
from astropy.coordinates import AltAz, Angle, Distance, EarthLocation, SkyCoord
from astropy.time import Time
from astropy.utils import iers

from . import _phasing
from .times import get_lst_for_time
from .tools import _get_autocorrelations_mask, _nants_to_nblts, _ntimes_to_nblts

try:
from lunarsky import MoonLocation, SkyCoord as LunarSkyCoord, Time as LTime
Expand Down Expand Up @@ -2572,3 +2573,124 @@
"lst": lst_array,
"site_loc": site_loc,
}


def _get_focus_xyz(uvd, focus, ra, dec):
"""
Return the x,y,z coordinates of the focal point.

The focal point corresponds to the location of
the NEAR-FIELD object of interest in the MWA-centred
ENU frame at each timestep.

Parameters
----------
uvd : UVData object
UVData object
focus : float
Focal distance of the array (km)
ra : float
Right ascension of the focal point ie phase center (deg; shape (Ntimes,))
dec : float
Declination of the focal point ie phase center (deg; shape (Ntimes,))

Returns
-------
x, y, z: ndarray, ndarray, ndarray
ENU-frame coordinates of the focal point (meters) (shape (Ntimes,))
"""
# Obtain timesteps
timesteps = Time(np.unique(uvd.time_array), format="jd")

Check warning on line 2603 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2603

Added line #L2603 was not covered by tests

# Initialize sky-based coordinates using right ascension and declination
obj = SkyCoord(ra * units.deg, dec * units.deg)

Check warning on line 2606 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2606

Added line #L2606 was not covered by tests

# The centre of the ENU frame should be located at the MEDIAN position of the array
loc = uvd.telescope.location.itrs.cartesian.xyz.value
antpos = uvd.telescope.antenna_positions + loc
x, y, z = np.median(antpos, axis=0)

Check warning on line 2611 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2609-L2611

Added lines #L2609 - L2611 were not covered by tests

# Initialize EarthLocation object centred on MWA
mwa = EarthLocation(x, y, z, unit=units.m)

Check warning on line 2614 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2614

Added line #L2614 was not covered by tests

# Convert sky object to an AltAz frame centred on the MWA
obj = obj.transform_to(AltAz(obstime=timesteps, location=mwa))

Check warning on line 2617 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2617

Added line #L2617 was not covered by tests

# Obtain altitude and azimuth
theta, phi = obj.alt.to(units.rad), obj.az.to(units.rad)

Check warning on line 2620 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2620

Added line #L2620 was not covered by tests

# Obtain x,y,z ENU coordinates
x = focus * 1e3 * np.cos(theta) * np.sin(phi)
y = focus * 1e3 * np.cos(theta) * np.cos(phi)
z = focus * 1e3 * np.sin(theta)

Check warning on line 2625 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2623-L2625

Added lines #L2623 - L2625 were not covered by tests

return x, y, z

Check warning on line 2627 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2627

Added line #L2627 was not covered by tests


def _get_delay(uvd, focus_x, focus_y, focus_z, flipconj):
"""
Calculate near-field phase/delay along the Nblts axis.

Parameters
----------
uvd : UVData object
UVData object
focus_x, focus_y, focus_z : ndarray, ndarray, ndarray
ENU-frame coordinates of focal point (Each of shape (Ntimes,))
flipconj : bool
Is the uvd conjugation scheme "flipped" compared to what pyuvdata expects?

Returns
-------
phi : ndarray
The phase correction to apply to each visibility along the Nblts axis
new_w : ndarray
The calculated near-field delay (or w-term) for each visibility along
the Nblts axis
"""
# Get indices to convert between Nants and Nblts
ind1, ind2 = _nants_to_nblts(uvd)

Check warning on line 2652 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2652

Added line #L2652 was not covered by tests

# Antenna positions in ENU frame
antpos = uvd.telescope.get_enu_antpos() - np.median(

Check warning on line 2655 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2655

Added line #L2655 was not covered by tests
uvd.telescope.get_enu_antpos(), axis=0
)

# Get tile positions for each baseline
tile1 = antpos[ind1] # Shape (Nblts, 3)
tile2 = antpos[ind2] # Shape (Nblts, 3)

Check warning on line 2661 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2660-L2661

Added lines #L2660 - L2661 were not covered by tests

# Focus points have shape (Ntimes,); convert to shape (Nblts,)
t_inds = _ntimes_to_nblts(uvd)
(focus_x, focus_y, focus_z) = (focus_x[t_inds], focus_y[t_inds], focus_z[t_inds])

Check warning on line 2665 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2664-L2665

Added lines #L2664 - L2665 were not covered by tests

# Calculate distance from antennas to focal point
# for each visibility along the Nblts axis
r1 = np.sqrt(

Check warning on line 2669 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2669

Added line #L2669 was not covered by tests
(tile1[:, 0] - focus_x) ** 2
+ (tile1[:, 1] - focus_y) ** 2
+ (tile1[:, 2] - focus_z) ** 2
)
r2 = np.sqrt(

Check warning on line 2674 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2674

Added line #L2674 was not covered by tests
(tile2[:, 0] - focus_x) ** 2
+ (tile2[:, 1] - focus_y) ** 2
+ (tile2[:, 2] - focus_z) ** 2
)

# Get the uvw array along the Nblts axis; select only the w's
old_w = uvd.uvw_array[:, -1]

Check warning on line 2681 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2681

Added line #L2681 was not covered by tests

# Calculate near-field delay
if flipconj:
new_w = r2 - r1

Check warning on line 2685 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2684-L2685

Added lines #L2684 - L2685 were not covered by tests
else:
new_w = r1 - r2
phi = new_w - old_w

Check warning on line 2688 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2687-L2688

Added lines #L2687 - L2688 were not covered by tests

# Remove autocorrelations
mask = _get_autocorrelations_mask(uvd)

Check warning on line 2691 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2691

Added line #L2691 was not covered by tests

new_w = new_w * mask + old_w * (1 - mask)
phi = phi * mask

Check warning on line 2694 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2693-L2694

Added lines #L2693 - L2694 were not covered by tests

return phi, new_w # Each of shape (Nblts,)

Check warning on line 2696 in src/pyuvdata/utils/phasing.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/phasing.py#L2696

Added line #L2696 was not covered by tests
97 changes: 97 additions & 0 deletions src/pyuvdata/utils/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,3 +368,100 @@
List containing the difference in unique entries between obj1 and obj2.
"""
return sorted(set(obj1)) if obj2 is None else sorted(set(obj1).difference(obj2))


def _nants_to_nblts(uvd):
"""
Obtain indices to convert (Nants,) to (Nblts,).

Parameters
----------
uvd : UVData object

Returns
-------
ind1, ind2 : ndarray, ndarray
index pairs to compose (Nblts,) shaped arrays for each
baseline from an (Nants,) shaped array
"""
ants = uvd.telescope.antenna_numbers

Check warning on line 387 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L387

Added line #L387 was not covered by tests

ant1 = uvd.ant_1_array
ant2 = uvd.ant_2_array

Check warning on line 390 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L389-L390

Added lines #L389 - L390 were not covered by tests

ind1 = []
ind2 = []

Check warning on line 393 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L392-L393

Added lines #L392 - L393 were not covered by tests

for i in ant1:
ind1.append(np.where(ants == i)[0][0])
for i in ant2:
ind2.append(np.where(ants == i)[0][0])

Check warning on line 398 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L395-L398

Added lines #L395 - L398 were not covered by tests

return np.asarray(ind1), np.asarray(ind2)

Check warning on line 400 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L400

Added line #L400 was not covered by tests


def _ntimes_to_nblts(uvd):
"""
Obtain indices to convert (Ntimes,) to (Nblts,).

Parameters
----------
uvd : UVData object
UVData object

Returns
-------
inds : ndarray
Indices that, when applied to an array of shape (Ntimes,),
correctly convert it to shape (Nblts,)
"""
unique_t = np.unique(uvd.time_array)
t = uvd.time_array

Check warning on line 419 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L418-L419

Added lines #L418 - L419 were not covered by tests

inds = []
for i in t:
inds.append(np.where(unique_t == i)[0][0])

Check warning on line 423 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L421-L423

Added lines #L421 - L423 were not covered by tests

return np.asarray(inds)

Check warning on line 425 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L425

Added line #L425 was not covered by tests


def _get_autocorrelations_mask(uvd):
"""
Get a (Nblts,) shaped array that masks autocorrelations.

Parameters
----------
uvd : UVData object
UVData object

Returns
-------
mask : ndarray
array of shape (Nblts,) of 1's and 0's,
where 0 indicates an autocorrelation
"""
# Get indices along the Nblts axis corresponding to autocorrelations
autos = []
for i in uvd.telescope.antenna_numbers:
num = uvd.antpair2ind(i, ant2=i)

Check warning on line 446 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L444-L446

Added lines #L444 - L446 were not covered by tests

if isinstance(num, slice):
inds = list(range(num.start, num.stop, num.step))
autos.append(inds)

Check warning on line 450 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L448-L450

Added lines #L448 - L450 were not covered by tests

elif num is not None:
autos.append(num)

Check warning on line 453 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L452-L453

Added lines #L452 - L453 were not covered by tests

# Flatten it to obtain the 1D array of autocorrelation indices
autos = np.asarray(autos).flatten()

Check warning on line 456 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L456

Added line #L456 was not covered by tests

# Initialize mask of ones (1 = not an autocorrelation)
mask = np.ones_like(uvd.baseline_array)

Check warning on line 459 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L459

Added line #L459 was not covered by tests

# Populate with zeros (0 = is an autocorrelation)
if (

Check warning on line 462 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L462

Added line #L462 was not covered by tests
len(autos) > 0
): # Protect against the case where the uvd is already free of autos
mask[autos] = 0

Check warning on line 465 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L465

Added line #L465 was not covered by tests

return mask

Check warning on line 467 in src/pyuvdata/utils/tools.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/utils/tools.py#L467

Added line #L467 was not covered by tests
105 changes: 97 additions & 8 deletions src/pyuvdata/uvdata/uvdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from ..telescopes import known_telescopes
from ..utils import phasing as phs_utils
from ..utils.io import hdf5 as hdf5_utils
from ..utils.phasing import _get_delay, _get_focus_xyz
from ..uvbase import UVBase
from .initializers import new_uvdata

Expand Down Expand Up @@ -4625,11 +4626,68 @@
elif (key == "cat_id") and (phase_dict[key] is not None):
# If this is the cat_id, make it an int
phase_dict[key] = int(phase_dict[key])
elif not ((phase_dict[key] is None) or isinstance(phase_dict[key], str)):
phase_dict[key] = float(phase_dict[key])

return phase_dict

def _apply_near_field_corrections(self, focus, ra, dec, flipconj=False):
"""
Apply near-field corrections by focusing the array to the specified focal point.

Parameters
----------
focus : astropy.units.Quantity object
Focal point of the array
ra : ndarray
Right ascension of the focal point ie phase center (rad; shape (Ntimes,))
dec : ndarray
Declination of the focal point ie phase center (rad; shape (Ntimes,))
flipconj : bool
Is the uvd conjugation scheme "flipped" compared to
what pyuvdata expects? (default False)

Returns
-------
None (performs operations inplace)
"""
# ------- Parameters that are independent of frequency --------

# Obtain focal distance in km
focus = focus.to(units.km).value

Check warning on line 4654 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4654

Added line #L4654 was not covered by tests

# Convert ra, dec from radians to degrees
ra, dec = np.degrees(ra), np.degrees(dec)

Check warning on line 4657 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4657

Added line #L4657 was not covered by tests

# Calculate the x, y, z coordinates of the focal point
# in ENU frame for each vis along Nblts axis
focus_x, focus_y, focus_z = _get_focus_xyz(self, focus, ra, dec)

Check warning on line 4661 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4661

Added line #L4661 was not covered by tests

# Calculate near-field correction at the specified timestep
# for each vis along Nblts axis
phi, new_w = _get_delay(self, focus_x, focus_y, focus_z, flipconj)

Check warning on line 4665 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4665

Added line #L4665 was not covered by tests

# Update old w with new w
self.uvw_array[:, -1] = new_w

Check warning on line 4668 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4668

Added line #L4668 was not covered by tests

# ---------------- Frequency-dependent calculations ---------------------

# Calculate wavelength associate with each frequency
wavelengths = 299792458 / self.freq_array

Check warning on line 4673 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4673

Added line #L4673 was not covered by tests

# Reshape the phi and wavelengths arrays in order to
# be able to broadcast them together
phi = np.reshape(phi, (phi.size, 1)) # (Nblts, 1)
wavelengths = np.reshape(wavelengths, (1, wavelengths.size)) # (1, Nfreqs)

Check warning on line 4678 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4677-L4678

Added lines #L4677 - L4678 were not covered by tests

# Calculate phase corrections at all frequencies
# -- produces shape (Nblts, Nfreqs)
phase_corrections = np.exp(-2j * np.pi * phi / wavelengths)

Check warning on line 4682 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4682

Added line #L4682 was not covered by tests

# Set data at each polarization (Npols = 4 usually)
for pol in self.polarization_array:
prev = np.reshape(self.get_data(pol), (self.Nblts, self.Nfreqs, 1))
corr = np.reshape(phase_corrections, (self.Nblts, self.Nfreqs, 1))

Check warning on line 4687 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4685-L4687

Added lines #L4685 - L4687 were not covered by tests

self.set_data(corr * prev, pol)

Check warning on line 4689 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4689

Added line #L4689 was not covered by tests

def phase(
self,
*,
Expand Down Expand Up @@ -4690,7 +4748,9 @@
cat_type : str
Type of phase center to be added. Must be one of:
"sidereal" (fixed RA/Dec), "ephem" (RA/Dec that moves with time),
"driftscan" (fixed az/el position). Default is "sidereal".
"driftscan" (fixed az/el position), "near_field" (applies near-field
corrections to the specified dist, assuming sidereal phase center).
Default is "sidereal".
ephem_times : ndarray of float
Only used when `cat_type="ephem"`. Describes the time for which the values
of `cat_lon` and `cat_lat` are caclulated, in units of JD. Shape is (Npts,).
Expand All @@ -4700,10 +4760,14 @@
pm_dec : float
Proper motion in Dec, in units of mas/year. Only used for sidereal phase
centers.
dist : float or ndarray of float
Distance of the source, in units of pc. Only used for sidereal and ephem
phase centers. Expected to be a float for sidereal phase
centers, and an ndarray of floats of shape (Npts,) for ephem phase centers.
dist : float or ndarray of float or astropy.units.Quantity object.
Distance to the source. Used for sidereal and ephem phase centers,
and for applying near-field corrections. If passed either as a float
(for sidereal phase centers) or as an ndarray of floats of shape (Npts,)
(for ephem phase centers), will be interpreted in units of parsec for all
cat_types except near_field; in the latter case it will be interpreted
in meters. Alternatively, an astropy.units.Quantity object may be passed
instead, in which case the units will be infered automatically.
vrad : float or ndarray of float
Radial velocity of the source, in units of km/s. Only used for sidereal and
ephem phase centers. Expected to be a float for sidereal phase
Expand Down Expand Up @@ -4747,6 +4811,25 @@
# Before moving forward with the heavy calculations, we need to do some
# basic housekeeping to make sure that we've got the coordinate data that
# we need in order to proceed.
if dist is not None:
if isinstance(dist, units.Quantity):
dist_qt = copy.deepcopy(dist)

Check warning on line 4816 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4815-L4816

Added lines #L4815 - L4816 were not covered by tests
else:
if cat_type == "near_field":
dist_qt = dist * units.m

Check warning on line 4819 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4818-L4819

Added lines #L4818 - L4819 were not covered by tests
else:
dist_qt = dist * units.parsec

Check warning on line 4821 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4821

Added line #L4821 was not covered by tests

dist = dist_qt.to(

Check warning on line 4823 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4823

Added line #L4823 was not covered by tests
units.parsec
).value # phase_dict internally stores in parsecs

if cat_type == "near_field":
near_field = True
cat_type = "sidereal" # apply far-field phasing BEFORE near-field

Check warning on line 4829 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4828-L4829

Added lines #L4828 - L4829 were not covered by tests
else:
near_field = False

phase_dict = self._phase_dict_helper(
lon=lon,
lat=lat,
Expand Down Expand Up @@ -4901,6 +4984,12 @@
if cleanup_old_sources:
self._clear_unused_phase_centers()

# Lastly, apply near-field corrections if specified
if near_field:
self._apply_near_field_corrections(

Check warning on line 4989 in src/pyuvdata/uvdata/uvdata.py

View check run for this annotation

Codecov / codecov/patch

src/pyuvdata/uvdata/uvdata.py#L4989

Added line #L4989 was not covered by tests
focus=dist_qt, ra=phase_dict["cat_lon"], dec=phase_dict["cat_lat"]
)

def phase_to_time(
self, time, *, phase_frame="icrs", use_ant_pos=True, select_mask=None
):
Expand Down
Loading