def get_antpos_ecef(antpos, lon): """ Compute the antenna positions in ECEF coordinates from rotECEF Args: antpos -- array of antenna positions. Should have shape (Nants, 3). lon (float) -- telescope longitude, in radians Returns: ecef -- array of antenna positions in ECEF frame. Has shape (Nants, 3) """ import pyuvdata.utils as uvutils ecef = uvutils.ECEF_from_rotECEF(antpos, lon) return ecef
def test_antpos_units(casa_uvfits, tmp_path): """ Read uvfits, write miriad. Check written antpos are in ns. """ uv = casa_uvfits testfile = str(tmp_path / "uv_antpos_units") uv.write_miriad(testfile, clobber=True) auv = aipy_extracts.UV(testfile) aantpos = auv["antpos"].reshape(3, -1).T * const.c.to("m/ns").value aantpos = aantpos[uv.antenna_numbers, :] aantpos = ( uvutils.ECEF_from_rotECEF(aantpos, uv.telescope_location_lat_lon_alt[1]) - uv.telescope_location ) assert np.allclose(aantpos, uv.antenna_positions)
def test_antpos_units(): """ Read uvfits, write miriad. Check written antpos are in ns. """ uv = UVData() uvfits_file = os.path.join(DATA_PATH, 'day2_TDEM0003_10s_norx_1src_1spw.uvfits') testfile = os.path.join(DATA_PATH, 'test/uv_antpos_units') uvtest.checkWarnings(uv.read_uvfits, [uvfits_file], message='Telescope EVLA is not') uv.write_miriad(testfile, clobber=True) auv = amiriad.UV(testfile) aantpos = auv['antpos'].reshape(3, -1).T * const.c.to('m/ns').value aantpos = aantpos[uv.antenna_numbers, :] aantpos = (uvutils.ECEF_from_rotECEF( aantpos, uv.telescope_location_lat_lon_alt[1]) - uv.telescope_location) nt.assert_true(np.allclose(aantpos, uv.antenna_positions))
def get_antpos_enu(antpos, lat, lon, alt): """ Compute the antenna positions in ENU coordinates from rotECEF. Args: antpos -- array of antenna positions. Should have shape (Nants, 3). lat (float) -- telescope latitude, in radians lon (float) -- telescope longitude, in radians alt (float) -- telescope altitude, in meters Returns: enu -- array of antenna positions in ENU frame. Has shape (Nants, 3). """ import pyuvdata.utils as uvutils ecef = uvutils.ECEF_from_rotECEF(antpos, lon) enu = uvutils.ENU_from_ECEF(ecef, lat, lon, alt) return enu
def test_mwa_ecef_conversion(): ''' Test based on comparing the antenna locations in a Cotter uvfits file to the antenna locations in MWA_tools. ''' test_data_file = os.path.join(DATA_PATH, 'mwa128_ant_layouts.npz') f = np.load(test_data_file) # From the STABXYZ table in a cotter-generated uvfits file, obsid = 1066666832 xyz = f['stabxyz'] # From the East/North/Height columns in a cotter-generated metafits file, obsid = 1066666832 enh = f['ENH'] # From a text file antenna_locations.txt in MWA_Tools/scripts txt_topo = f['txt_topo'] # From the unphased uvw coordinates of obsid 1066666832, positions relative to antenna 0 # these aren't used in the current test, but are interesting and might help with phasing diagnosis in the future uvw_topo = f['uvw_topo'] # Sky coordinates are flipped for uvw derived values uvw_topo = -uvw_topo uvw_topo += txt_topo[0] # transpose these arrays to get them into the right shape txt_topo = txt_topo.T uvw_topo = uvw_topo.T enh = enh.T # ARRAYX, ARRAYY, ARRAYZ in ECEF frame from Cotter file arrcent = f['arrcent'] lat, lon, alt = uvutils.LatLonAlt_from_XYZ(arrcent) # The STABXYZ coordinates are defined with X through the local meridian, # so rotate back to the prime meridian new_xyz = uvutils.ECEF_from_rotECEF(xyz.T, lon) # add in array center to get real ECEF ecef_xyz = new_xyz + arrcent enu = uvutils.ENU_from_ECEF(ecef_xyz.T, lat, lon, alt) nt.assert_true(np.allclose(enu, enh)) # test other direction of ECEF rotation rot_xyz = uvutils.rotECEF_from_ECEF(new_xyz, lon) nt.assert_true(np.allclose(rot_xyz.T, xyz))
uvd.telescope_location_lat_lon_alt = (cofa_loc.lat * np.pi / 180., cofa_loc.lon * np.pi / 180., cofa_loc.elevation) # loop over aa object idx = 0 antpos = np.zeros((len(aa), 3)) ants_telescope = [] for iant, ant in enumerate(aa): # test to see if antenna is "far" from center of the Earth if np.linalg.norm(ant.pos) > 1e6: # convert from ns -> m pos = ant.pos * c_ns # rotate from rotECEF -> ECEF pos_ecef = uvutils.ECEF_from_rotECEF(pos, longitude) # subtract off array location, to get just relative positions rel_pos = pos_ecef - uvd.telescope_location # save in array antpos[idx, :] = rel_pos # also save antenna number to list of antennas ants_telescope.append(iant) # increment counter idx += 1 # set the antenna information uvd.Nants_telescope = len(ants_telescope)