def test_single_zenith_source_uvdata(): """Test single zenith source using test uvdata file.""" hera_uv = UVData() hera_uv.read_uvfits(EW_uvfits_file) time = Time(hera_uv.time_array[0], scale='utc', format='jd') array_location = EarthLocation.from_geocentric( hera_uv.telescope_location[0], hera_uv.telescope_location[1], hera_uv.telescope_location[2], unit='m') freq = hera_uv.freq_array[0, 0] * units.Hz # get antennas positions into ENU antpos = hera_uv.antenna_positions[0:2, :] + hera_uv.telescope_location antpos = uvutils.ENU_from_ECEF(antpos.T, *hera_uv.telescope_location_lat_lon_alt).T antenna1 = pyuvsim.Antenna('ant1', 1, np.array(antpos[0, :]), 0) antenna2 = pyuvsim.Antenna('ant2', 2, np.array(antpos[1, :]), 0) # setup the things that don't come from pyuvdata: # make a source at zenith time.location = array_location source = create_zenith_source(time, 'zensrc') beam = UVBeam() beam.read_cst_beam(beam_files, beam_type='efield', frequency=[100e6, 123e6], telescope_name='HERA', feed_name='PAPER', feed_version='0.1', feed_pol=['x'], model_name='E-field pattern - Rigging height 4.9m', model_version='1.0') beam_list = [beam] baseline = pyuvsim.Baseline(antenna1, antenna2) array = pyuvsim.Telescope('telescope_name', array_location, beam_list) task = pyuvsim.UVTask(source, time, freq, baseline, array) engine = pyuvsim.UVEngine(task) visibility = engine.make_visibility() nt.assert_true(np.allclose(visibility, np.array([.5, .5, 0, 0]), atol=5e-3))
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))
def test_file_to_tasks(): hera_uv = UVData() hera_uv.read_uvfits(EW_uvfits_file) time = Time(hera_uv.time_array[0], scale='utc', format='jd') sources = np.array([create_zenith_source(time, 'zensrc')]) beam = UVBeam() beam.read_cst_beam(beam_files, beam_type='efield', frequency=[150e6, 123e6], telescope_name='HERA', feed_name='PAPER', feed_version='0.1', feed_pol=['x'], model_name='E-field pattern - Rigging height 4.9m', model_version='1.0') beam_list = [beam] uvtask_list = pyuvsim.uvdata_to_task_list(hera_uv, sources, beam_list) tel_loc = EarthLocation.from_geocentric(*hera_uv.telescope_location, unit='m') beam = UVBeam() beam.read_cst_beam(beam_files, beam_type='efield', frequency=[150e6, 123e6], telescope_name='HERA', feed_name='PAPER', feed_version='0.1', feed_pol=['x'], model_name='E-field pattern - Rigging height 4.9m', model_version='1.0') beam_list = [beam] telescope = pyuvsim.Telescope(hera_uv.telescope_name, tel_loc, beam_list) ant_pos = hera_uv.antenna_positions + hera_uv.telescope_location ant_pos_enu = uvutils.ENU_from_ECEF( ant_pos.T, *hera_uv.telescope_location_lat_lon_alt).T expected_task_list = [] antenna_names = hera_uv.antenna_names antennas = [] for num, antname in enumerate(antenna_names): beam_id = 0 antennas.append( pyuvsim.Antenna(antname, num, ant_pos_enu[num], beam_id)) antennas1 = [] for antnum in hera_uv.ant_1_array: index = np.where(hera_uv.antenna_numbers == antnum)[0][0] antennas1.append(antennas[index]) antennas2 = [] for antnum in hera_uv.ant_2_array: index = np.where(hera_uv.antenna_numbers == antnum)[0][0] antennas2.append(antennas[index]) for idx, antenna1 in enumerate(antennas1): antenna2 = antennas2[idx] baseline = pyuvsim.Baseline(antenna1, antenna2) task = pyuvsim.UVTask(sources[0], time.jd, hera_uv.freq_array[0, 0], baseline, telescope) task.uvdata_index = (idx, 0, 0) expected_task_list.append(task) for idx, task in enumerate(uvtask_list): exp_task = expected_task_list[idx] nt.assert_equal(task, exp_task)
def test_single_offzenith_source_miriad(): """Test single off-zenith source using test uvdata file.""" miriad_uv = UVData() miriad_uv.read_miriad(os.path.join(DATA_PATH, 'hera_testfile'), ant_str='9_10') miriad_uv.select(times=miriad_uv.time_array[0]) src_az = Angle('90.0d') src_alt = Angle('85.0d') src_za = Angle('90.0d') - src_alt src_l = np.sin(src_az.rad) * np.sin(src_za.rad) src_m = np.cos(src_az.rad) * np.sin(src_za.rad) src_n = np.cos(src_za.rad) time = Time(miriad_uv.time_array[0], scale='utc', format='jd') array_location = EarthLocation.from_geocentric( miriad_uv.telescope_location[0], miriad_uv.telescope_location[1], miriad_uv.telescope_location[2], unit='m') freq = miriad_uv.freq_array[0, 0] * units.Hz # get antennas positions into ENU antpos = miriad_uv.antenna_positions[0:2, :] + miriad_uv.telescope_location antpos = uvutils.ENU_from_ECEF(antpos.T, *miriad_uv.telescope_location_lat_lon_alt).T antenna1 = pyuvsim.Antenna('ant1', 1, np.array(antpos[0, :]), 0) antenna2 = pyuvsim.Antenna('ant2', 2, np.array(antpos[1, :]), 0) # setup the things that don't come from pyuvdata: # make a source off zenith time.location = array_location source = create_offzenith_source(time, 'offzensrc', az=src_az, alt=src_alt) beam = UVBeam() beam.read_cst_beam(beam_files, beam_type='efield', frequency=[100e6, 123e6], telescope_name='HERA', feed_name='PAPER', feed_version='0.1', feed_pol=['x'], model_name='E-field pattern - Rigging height 4.9m', model_version='1.0') beam_list = [beam] baseline = pyuvsim.Baseline(antenna1, antenna2) array = pyuvsim.Telescope('telescope_name', array_location, beam_list) task = pyuvsim.UVTask(source, time, freq, baseline, array) engine = pyuvsim.UVEngine(task) visibility = engine.make_visibility() # analytically calculate visibility beam.peak_normalize() beam.interpolation_function = 'az_za_simple' interpolated_beam, interp_basis_vector = beam.interp( az_array=np.array([src_az.rad]), za_array=np.array([src_za.rad]), freq_array=np.array([freq.to('Hz').value])) jones = np.zeros((2, 2), dtype=np.complex64) jones[0, 0] = interpolated_beam[1, 0, 0, 0, 0] jones[1, 1] = interpolated_beam[0, 0, 1, 0, 0] jones[1, 0] = interpolated_beam[1, 0, 1, 0, 0] jones[0, 1] = interpolated_beam[0, 0, 0, 0, 0] uvw_wavelength_array = hera_uv.uvw_array * units.m / const.c * freq.to( '1/s') vis_analytic = 0.5 * np.dot( jones, np.conj(jones).T) * np.exp( -2j * np.pi * (uvw_wavelength_array[0, 0] * src_l + uvw_wavelength_array[0, 1] * src_m + uvw_wavelength_array[0, 2] * src_n)) vis_analytic = np.array([ vis_analytic[0, 0], vis_analytic[1, 1], vis_analytic[1, 0], vis_analytic[0, 1] ]) print('Analytic visibility', vis_analytic) print('Calculated visibility', visibility) nt.assert_true(np.allclose(visibility, vis_analytic, atol=5e-3))
import re parser = argparse.ArgumentParser( description='Plot auto locations and magnitudes') parser.add_argument('file', metavar='file', type=str, nargs='+', help='File to be processed.') args = parser.parse_args() uv = pyuvdata.UVData() uv.read_miriad(args.file) antpos = uv.antenna_positions + uv.telescope_location antpos = uvutils.ENU_from_ECEF(antpos.T, *uv.telescope_location_lat_lon_alt).T amps = np.zeros(uv.Nants_telescope) for ant in range(uv.Nants_telescope): d = uv.get_data((uv.antenna_numbers[ant], uv.antenna_numbers[ant])) amps[ant] = np.median(np.abs(d)) at_time = time.Time(uv.extra_keywords['obsid'], format='gps') h = sys_handling.Handling() pol = uvutils.polnum2str(uv.polarization_array[0])[0] if pol == 'X': pol = 'e' else: pol = 'n' f = plt.figure(figsize=(10, 8))
# Convert UTM to Lat/Lon # LatLon to ECEF using pyuvdata.utils # # Finally convert ECEF to ENU using # coordinates of the center of the array (cofa) # ENU coordinates are wrt center of the array antpos_ENU = {} # Extract cminfo from redis for cofa coordinates cminfo = redis_cm.read_cminfo_from_redis(return_as='dict') cofa_lat = cminfo['cofa_lat'] * np.pi / 180. cofa_lon = cminfo['cofa_lon'] * np.pi / 180. cofa_alt = cminfo['cofa_alt'] for ant, loc in ants.items(): lon, lat = latlon.transform_point(loc['E'], loc['N'] - lat_corr, utm) # Convert the latitute-longitude to ECEF ecef = uvutils.XYZ_from_LatLonAlt(lat * np.pi / 180, lon * np.pi / 180, loc['elevation']) # Convert ECEF to ENU enu = uvutils.ENU_from_ECEF(ecef, cofa_lat, cofa_lon, cofa_alt) antpos_ENU[ant] = enu.tolist() with open('HERA_350_ENU.json', 'w') as fp: json.dump(antpos_ENU, fp)
def setup_uvdata( array_layout=None, telescope_location=None, telescope_name=None, Nfreqs=None, start_freq=None, bandwidth=None, freq_array=None, Ntimes=None, time_cadence=None, start_time=None, time_array=None, bls=None, anchor_ant=None, antenna_nums=None, no_autos=True, pols=["xx"], make_full=False, redundancy=None, run_check=True, ): """ Setup a UVData object for simulating. Args: array_layout : str Filepath to array layout in ENU coordinates [meters] telescope_location : len-3 tuple Telescope location on Earth in LatLonAlt coordinates [deg, deg, meters] telescope_name : str Name of telescope Nfreqs : int Number of frequency channels start_freq : float Starting frequency [Hz] bandwidth : float Total frequency bandwidth of spectral window [Hz] freq_array : ndarray frequency array [Hz], cannot be specified if start_freq, Nfreqs or bandwidth is specified Ntimes : int Number of integration bins time_cadence : float Cadence of time bins [seconds] start_time : float Time of the first integration bin [Julian Date] time_array : ndarray time array [Julian Date], cannot be specified if start_time, Ntimes and time_cadence is specified bls : list List of antenna-pair tuples for baseline selection anchor_ant: int Selects baselines such that one of the pair is a specified antenna number redundancy: float Redundant baseline selection tolerance for selection antenna_nums : list List of antenna numbers to keep in array make_full : Generate the full UVData object, includes arrays of length Nblts. Default behavior creates an invalid UVData object, where baseline_array has length Nbls, etc. This is to avoid excessive memory usage up front when it's not necessary. Returns: UVData object with zeroed data_array """ # get antenna information tele_dict = parse_telescope_params( dict( array_layout=array_layout, telescope_location=telescope_location, telescope_name=telescope_name, )) lat, lon, alt = uvutils.LatLonAlt_from_XYZ(tele_dict["telescope_location"]) antpos = tele_dict["antenna_positions"] enu = uvutils.ENU_from_ECEF( tele_dict["antenna_positions"] + tele_dict["telescope_location"], lat, lon, alt) anums = tele_dict["antenna_numbers"] antnames = tele_dict["antenna_names"] Nants = tele_dict["Nants_data"] # setup object and fill in basic info uv_obj = UVData() uv_obj.telescope_location = tele_dict["telescope_location"] uv_obj.telescope_location_lat_lon_alt = (lat, lon, alt) uv_obj.telescope_location_lat_lon_alt_degrees = ( np.degrees(lat), np.degrees(lon), alt, ) uv_obj.antenna_numbers = anums uv_obj.antenna_names = antnames uv_obj.antenna_positions = antpos uv_obj.Nants_telescope = Nants # fill in frequency and time info: wait to fill in len-Nblts arrays until later if freq_array is not None: if Nfreqs is not None or start_freq is not None or bandwidth is not None: raise ValueError( "Cannot specify freq_array as well as Nfreqs, start_freq or bandwidth" ) if freq_array.ndim == 1: freq_array = freq_array.reshape(1, -1) Nfreqs = freq_array.size else: freq_dict = parse_frequency_params( dict(Nfreqs=Nfreqs, start_freq=start_freq, bandwidth=bandwidth)) freq_array = freq_dict["freq_array"] if time_array is not None: if Ntimes is not None or start_time is not None or time_cadence is not None: raise ValueError( "Cannot specify time_array as well as Ntimes, start_time or time_cadence" ) Ntimes = time_array.size else: time_dict = parse_time_params( dict(Ntimes=Ntimes, start_time=start_time, time_cadence=time_cadence)) time_array = time_dict["time_array"] uv_obj.freq_array = freq_array uv_obj.Nfreqs = Nfreqs uv_obj.Ntimes = Ntimes # fill in other attributes uv_obj.spw_array = np.array([0], dtype=int) uv_obj.Nspws = 1 uv_obj.polarization_array = np.array( [uvutils.polstr2num(pol) for pol in pols], dtype=int) uv_obj.Npols = uv_obj.polarization_array.size if uv_obj.Nfreqs > 1: uv_obj.channel_width = np.diff(uv_obj.freq_array[0])[0] else: uv_obj.channel_width = 1.0 uv_obj._set_drift() uv_obj.telescope_name = tele_dict["telescope_name"] uv_obj.instrument = "simulator" uv_obj.object_name = "zenith" uv_obj.vis_units = "Jy" uv_obj.history = "" if redundancy is not None: red_tol = redundancy reds, vec_bin_centers, lengths = uvutils.get_antenna_redundancies( anums, enu, tol=red_tol, include_autos=not bool(no_autos)) bls = [r[0] for r in reds] bls = [uvutils.baseline_to_antnums(bl_ind, Nants) for bl_ind in bls] # Setup array and implement antenna/baseline selections. bl_array = [] _bls = [(a1, a2) for a1 in anums for a2 in anums if a1 <= a2] if bls is not None: if isinstance(bls, str): bls = ast.literal_eval(bls) bls = [bl for bl in _bls if bl in bls] else: bls = _bls if anchor_ant is not None: bls = [bl for bl in bls if anchor_ant in bl] if bool(no_autos): bls = [bl for bl in bls if bl[0] != bl[1]] if antenna_nums is not None: if isinstance(antenna_nums, str): antenna_nums = ast.literal_eval(antenna_nums) if isinstance(antenna_nums, int): antenna_nums = [antenna_nums] bls = [(a1, a2) for (a1, a2) in bls if a1 in antenna_nums or a2 in antenna_nums] bls = sorted(bls) for (a1, a2) in bls: bl_array.append(uvutils.antnums_to_baseline(a1, a2, 1)) bl_array = np.asarray(bl_array) print("Nbls: {}".format(bl_array.size)) if bl_array.size == 0: raise ValueError("No baselines selected.") uv_obj.time_array = time_array # Keep length Ntimes uv_obj.baseline_array = bl_array # Length Nbls if make_full: uv_obj = complete_uvdata(uv_obj, run_check=run_check) return uv_obj
Nprocs = int(param_dict['Nprocs']) else: Nprocs = 1 sjob_id = None if 'SLURM_JOB_ID' in os.environ: sjob_id = os.environ['SLURM_JOB_ID'] print("Nprocs: ", Nprocs) sys.stdout.flush() # --------------------------- # Observatory # --------------------------- lat, lon, alt = uvutils.LatLonAlt_from_XYZ(tele_dict['telescope_location']) antpos = tele_dict['antenna_positions'] enu = uvutils.ENU_from_ECEF(tele_dict['antenna_positions'] + tele_dict['telescope_location'], lat, lon, alt) anums = tele_dict['antenna_numbers'] antnames = tele_dict['antenna_names'] Nants = tele_dict['Nants_data'] uv_obj = UVData() uv_obj.telescope_location = tele_dict['telescope_location'] uv_obj.telescope_location_lat_lon_alt = (lat, lon, alt) uv_obj.telescope_location_lat_lon_alt_degrees = (np.degrees(lat), np.degrees(lon), alt) uv_obj.antenna_numbers = anums uv_obj.antenna_names = antnames uv_obj.antenna_positions = antpos uv_obj.Nants_telescope = Nants uv_obj.Ntimes = time_dict['Ntimes'] Ntimes = time_dict['Ntimes'] uv_obj.freq_array = freq_dict['freq_array']
else: low_lim = np.pi / 2 - 0.5 * opts.width * np.pi / 180 high_lim = np.pi / 2 + 0.5 * opts.width * np.pi / 180 hours = np.linspace(low_lim, high_lim, 10) decs = np.ones_like(hours) * np.pi / 2 #zenith transitting point source uv = UVData() if opts.data is not None: # Read in telescope data if opts.data.endswith('.uvfits'): uv.read_uvfits(opts.data) else: uv.read_miriad(opts.data) ant_pos = uv.antenna_positions + uv.telescope_location lat, lon, alt = uv.telescope_location_lat_lon_alt ant_pos = uvu.ENU_from_ECEF(ant_pos.T, lat, lon, alt).T blns = uv.get_baseline_nums() elif opts.positions is not None: # Read in antenna positions from file ant_pos = np.load(opts.positions) blns = np.zeros(0, dtype=int) # ant_1_array = np.zeros(0, dtype=int) # ant_2_array = np.zeros(0, dtype=int) num_ants = ant_pos.shape[0] ant_nums = range(1, num_ants + 1) # for i in range(len(ant_nums)): for ant1 in ant_nums: # ant1 = ant_nums[i] # for j in range(len(ant_nums)): for ant2 in ant_nums:
def calculate_caldata(self): """Returns a dictionary of baseline lengths and the corresponding pairs. The data is based on a calfile. ex_ants is a list of integers that specify antennae to be exlcuded from calculation. Requires cal file to be in PYTHONPATH.""" if self.Zeus.calfile: try: print('Reading calfile: %s...' % self.Zeus.calfile) exec('import %s as cal' % self.Zeus.calfile, globals(), locals()) antennae = cal.prms['antpos_ideal'] except ImportError: raise Exception('Unable to import: %s' % self.Zeus.calfile) elif self.uvd: # Build antenna positions from data file itself. print('Generating calibration information from MIRIAD file.') antennae = {} lat, lon, alt = self.uvd.telescope_location_lat_lon_alt for i, antnum in enumerate(self.uvd.antenna_numbers): pos = self.uvd.antenna_positions[ i, :] + self.uvd.telescope_location xyz = uvutils.ENU_from_ECEF(pos, latitude=lat, longitude=lon, altitude=alt) antennae[antnum] = { 'top_x': xyz[0], 'top_y': xyz[1], 'top_z': xyz[2] } else: raise Exception( 'UVData object does not exist. Try supplying a calfile.') # Check that self.Zeus.exants contain only antennae that exist if not set(self.Zeus.exants).issubset(set(antennae.keys())): raise Exception('You provided invalid antenna(e) to exclude.') # Remove all placeholder antennae from consideration # Remove all antennae from exants from consideration ants = [] for ant in antennae.keys(): if (not antennae[ant]['top_z'] == -1) and (ant not in self.Zeus.exants): ants.append(ant) ants = np.array(ants) # Set the bins for binning the baselines bins_baseline = np.arange(0, 750, self.Zeus.BIN_WIDTH) # Initialize baselines, slopes, pairs arrays baselines = np.array([], dtype=np.float128) slopes = np.array([], dtype=np.float128) pairs = {} # Cycle through antennae to create pairs for ant_i in ants: for ant_j in ants: if ant_i >= ant_j: continue pair = (ant_i, ant_j) # Find the baseline length of the pair, bin it, format it, and add it to the baselines array dx = antennae[pair[1]]['top_x'] - antennae[pair[0]]['top_x'] dy = antennae[pair[1]]['top_y'] - antennae[pair[0]]['top_y'] baseline = np.sqrt(np.power(dx, 2) + np.power(dy, 2)) baseline = np.round(baseline, decimals=2) baseline = np.digitize(baseline, bins_baseline) * self.Zeus.BIN_WIDTH baselines = np.append(baselines, baseline) # Find the slope of the pair, format it, and add it to the slopes array dy = antennae[pair[1]]['top_y'] - antennae[pair[0]]['top_y'] dx = antennae[pair[1]]['top_x'] - antennae[pair[0]]['top_x'] if dx != 0: slope = float(np.round(dy / dx, decimals=2)) else: slope = np.inf slopes = np.append(slopes, slope) # Add the pair and its slope and baseline to the pairs dictionary: {(ant_1, ant_2): (baseline, slope), ...} pairs[pair] = (np.float(np.round(baseline, 1)), np.float(np.round(slope, 2))) # Sort and remove duplicates from baselines and slopes baselines = np.unique(np.sort(baselines)) slopes = np.unique(np.sort(slopes)) # Sort pairs into antdict and slopedict antdict = {} slopedict = {} for pair, (baseline, slope) in pairs.items(): if baseline in antdict: antdict[baseline].append(pair) else: antdict[baseline] = [pair] if baseline in slopedict: if slope in slopedict[baseline]: slopedict[baseline][slope].append(pair) else: slopedict[baseline][slope] = [pair] else: slopedict[baseline] = {slope: []} slopedict[baseline][slope].append(pair) self.caldata = { 'antdict': antdict, 'slopedict': slopedict, 'pairs': pairs, 'baselines': baselines, 'slopes': slopes }
def test_ENU_tofrom_ECEF(): center_lat = -30.7215261207 * np.pi / 180.0 center_lon = 21.4283038269 * np.pi / 180.0 center_alt = 1051.7 lats = np.array([ -30.72218216, -30.72138101, -30.7212785, -30.7210011, -30.72159853, -30.72206199, -30.72174614, -30.72188775, -30.72183915, -30.72100138 ]) * np.pi / 180.0 lons = np.array([ 21.42728211, 21.42811727, 21.42814544, 21.42795736, 21.42686739, 21.42918772, 21.42785662, 21.4286408, 21.42750933, 21.42896567 ]) * np.pi / 180.0 alts = np.array([ 1052.25, 1051.35, 1051.2, 1051., 1051.45, 1052.04, 1051.68, 1051.87, 1051.77, 1051.06 ]) # used pymap3d, which implements matlab code, as a reference. x = [ 5109327.46674067, 5109339.76407785, 5109344.06370947, 5109365.11297147, 5109372.115673, 5109266.94314734, 5109329.89620962, 5109295.13656657, 5109337.21810468, 5109329.85680612 ] y = [ 2005130.57953031, 2005221.35184577, 2005225.93775268, 2005214.8436201, 2005105.42364036, 2005302.93158317, 2005190.65566222, 2005257.71335575, 2005157.78980089, 2005304.7729239 ] z = [ -3239991.24516348, -3239914.4185286, -3239904.57048431, -3239878.02656316, -3239935.20415493, -3239979.68381865, -3239949.39266985, -3239962.98805772, -3239958.30386264, -3239878.08403833 ] east = [ -97.87631659, -17.87126443, -15.17316938, -33.19049252, -137.60520964, 84.67346748, -42.84049408, 32.28083937, -76.1094745, 63.40285935 ] north = [ -72.7437482, 16.09066646, 27.45724573, 58.21544651, -8.02964511, -59.41961437, -24.39698388, -40.09891961, -34.70965816, 58.18410876 ] up = [ 0.54883333, -0.35004539, -0.50007736, -0.70035299, -0.25148791, 0.33916067, -0.02019057, 0.16979185, 0.06945155, -0.64058124 ] xyz = uvutils.XYZ_from_LatLonAlt(lats, lons, alts) assert np.allclose(np.stack((x, y, z), axis=1), xyz, atol=1e-3) enu = uvutils.ENU_from_ECEF(xyz, center_lat, center_lon, center_alt) assert np.allclose(np.stack((east, north, up), axis=1), enu, atol=1e-3) # check warning if array transposed uvtest.checkWarnings(uvutils.ENU_from_ECEF, [xyz.T, center_lat, center_lon, center_alt], message='The expected shape of ECEF xyz array', category=DeprecationWarning) # check warning if 3 x 3 array uvtest.checkWarnings(uvutils.ENU_from_ECEF, [xyz[0:3], center_lat, center_lon, center_alt], message='The xyz array in ENU_from_ECEF is', category=DeprecationWarning) # check error if only 2 coordinates pytest.raises(ValueError, uvutils.ENU_from_ECEF, xyz[:, 0:2], center_lat, center_lon, center_alt) # check that a round trip gives the original value. xyz_from_enu = uvutils.ECEF_from_ENU(enu, center_lat, center_lon, center_alt) assert np.allclose(xyz, xyz_from_enu, atol=1e-3) # check warning if array transposed uvtest.checkWarnings(uvutils.ECEF_from_ENU, [enu.T, center_lat, center_lon, center_alt], message='The expected shape the ENU array', category=DeprecationWarning) # check warning if 3 x 3 array uvtest.checkWarnings(uvutils.ECEF_from_ENU, [enu[0:3], center_lat, center_lon, center_alt], message='The enu array in ECEF_from_ENU is', category=DeprecationWarning) # check error if only 2 coordinates pytest.raises(ValueError, uvutils.ENU_from_ECEF, enu[:, 0:2], center_lat, center_lon, center_alt) # check passing a single value enu_single = uvutils.ENU_from_ECEF(xyz[0, :], center_lat, center_lon, center_alt) assert np.allclose(np.array((east[0], north[0], up[0])), enu[0, :], atol=1e-3) xyz_from_enu = uvutils.ECEF_from_ENU(enu_single, center_lat, center_lon, center_alt) assert np.allclose(xyz[0, :], xyz_from_enu, atol=1e-3) # error checking pytest.raises(ValueError, uvutils.ENU_from_ECEF, xyz[:, 0:1], center_lat, center_lon, center_alt) pytest.raises(ValueError, uvutils.ECEF_from_ENU, enu[:, 0:1], center_lat, center_lon, center_alt) pytest.raises(ValueError, uvutils.ENU_from_ECEF, xyz / 2., center_lat, center_lon, center_alt)
from astropy import constants, coordinates, units from astropy.time import Time from astropy.coordinates import SkyCoord, EarthLocation, FK5 from pyuvdata import utils as uvutils from hera_mc import geo_handling # get cofa information handling = geo_handling.Handling() cofa = handling.cofa()[0] cofa_lat = cofa.lat * np.pi / 180.0 cofa_lon = cofa.lon * np.pi / 180.0 cofa_alt = cofa.elevation cofa_xyz = uvutils.XYZ_from_LatLonAlt(cofa_lat, cofa_lon, cofa_alt) cofa_enu = uvutils.ENU_from_ECEF(cofa_xyz, cofa_lat, cofa_lon, cofa_alt) # get antennas telescope_location = EarthLocation.from_geocentric(*cofa_xyz, unit=units.m) jd = int(Time.now().jd) if True: time0 = Time.now() time0.location = telescope_location else: time0 = Time(jd, format="jd", location=telescope_location) print("time0: ", time0.jd) ants = handling.get_active_stations(time0, "all") # sort the list by antenna name ants = sorted(ants, key=lambda x: int(x.station_name[2:])) # convert from lat/lon/alt to xyz
else: Nprocs = 1 sjob_id = None if "SLURM_JOB_ID" in os.environ: sjob_id = os.environ["SLURM_JOB_ID"] print("Nprocs: ", Nprocs) sys.stdout.flush() # --------------------------- # Observatory # --------------------------- lat, lon, alt = uvutils.LatLonAlt_from_XYZ(tele_dict["telescope_location"]) antpos = tele_dict["antenna_positions"] enu = uvutils.ENU_from_ECEF( tele_dict["antenna_positions"] + tele_dict["telescope_location"], lat, lon, alt) anums = tele_dict["antenna_numbers"] antnames = tele_dict["antenna_names"] Nants = tele_dict["Nants_data"] uv_obj = UVData() uv_obj.telescope_location = tele_dict["telescope_location"] uv_obj.telescope_location_lat_lon_alt = (lat, lon, alt) uv_obj.telescope_location_lat_lon_alt_degrees = (np.degrees(lat), np.degrees(lon), alt) uv_obj.antenna_numbers = anums uv_obj.antenna_names = antnames uv_obj.antenna_positions = antpos uv_obj.Nants_telescope = Nants uv_obj.Ntimes = time_dict["Ntimes"]