Beispiel #1
0
def jd_to_lst(JD_time, telescope='HERA'):
    """Converts fractional JD of HERAData object into LAST

    :param JD: Julian time
    :type JD: float, str
    :param telescope: Known telescope to pyuvdata
    :type telescope: str

    :return: Local (Apparent) sidereal time
    :rtype: float
    """
    lat_lon_alt = pyuvdata.telescopes.get_telescope(
        telescope).telescope_location_lat_lon_alt_degrees
    lst = uvutils.get_lst_for_time([JD_time], *lat_lon_alt)
    return lst[0]
Beispiel #2
0
def lst_from_uv(uv):
    ''' Calculate the lst_array for a UVData or UVCal object.
    Args:
        uv: a UVData or UVCal object.
    Returns:
        lst_array: lst_array corresponding to time_array and at telecope location.
                   Units are radian.
    '''
    if not isinstance(uv, (UVCal, UVData)):
        raise ValueError('Function lst_from_uv can only operate on '
                         'UVCal or UVData object.')

    tel = uvtel.get_telescope(uv.telescope_name)
    lat, lon, alt = tel.telescope_location_lat_lon_alt_degrees
    lst_array = uvutils.get_lst_for_time(uv.time_array, lat, lon, alt)
    return lst_array
Beispiel #3
0
def test_readMiriadwriteMiriad_check_time_format():
    """
    test time_array is converted properly from Miriad format
    """
    # test read-in
    fname = os.path.join(DATA_PATH, 'zen.2457698.40355.xx.HH.uvcA')
    uvd = UVData()
    uvd.read(fname)
    uvd_t = uvd.time_array.min()
    uvd_l = uvd.lst_array.min()
    uv = aipy_extracts.UV(fname)
    uv_t = uv['time'] + uv['inttime'] / (24 * 3600.) / 2

    lat, lon, alt = uvd.telescope_location_lat_lon_alt
    t1 = Time(uv['time'], format='jd', location=(lon, lat))
    dt = TimeDelta(uv['inttime'] / 2, format='sec')
    t2 = t1 + dt
    lsts = uvutils.get_lst_for_time(np.array([t1.jd, t2.jd]), lat, lon, alt)
    delta_lst = lsts[1] - lsts[0]
    uv_l = uv['lst'] + delta_lst

    # assert starting time array and lst array are shifted by half integration
    assert np.isclose(uvd_t, uv_t)

    # avoid errors if IERS table is too old (if the iers url is down)
    if iers.conf.auto_max_age is None and six.PY2:
        tolerance = 2e-5
    else:
        tolerance = 1e-8
    assert np.allclose(uvd_l, uv_l, atol=tolerance)
    # test write-out
    fout = os.path.join(DATA_PATH, 'ex_miriad')
    uvd.write_miriad(fout, clobber=True)
    # assert equal to original miriad time
    uv2 = aipy_extracts.UV(fout)
    assert np.isclose(uv['time'], uv2['time'])
    assert np.isclose(uv['lst'], uv2['lst'], atol=tolerance)
    if os.path.exists(fout):
        shutil.rmtree(fout)
Beispiel #4
0
def test_readmiriad_write_miriad_check_time_format(tmp_path):
    """
    test time_array is converted properly from Miriad format
    """
    from pyuvdata.uvdata import aipy_extracts

    # test read-in
    fname = os.path.join(DATA_PATH, "zen.2457698.40355.xx.HH.uvcA")
    uvd = UVData()
    uvd.read(fname)
    uvd_t = uvd.time_array.min()
    uvd_l = uvd.lst_array.min()
    uv = aipy_extracts.UV(fname)
    uv_t = uv["time"] + uv["inttime"] / (24 * 3600.0) / 2

    lat, lon, alt = uvd.telescope_location_lat_lon_alt
    t1 = Time(uv["time"], format="jd", location=(lon, lat))
    dt = TimeDelta(uv["inttime"] / 2, format="sec")
    t2 = t1 + dt
    lsts = uvutils.get_lst_for_time(np.array([t1.jd, t2.jd]), lat, lon, alt)
    delta_lst = lsts[1] - lsts[0]
    uv_l = uv["lst"] + delta_lst

    # assert starting time array and lst array are shifted by half integration
    assert np.isclose(uvd_t, uv_t)

    # avoid errors if IERS table is too old (if the iers url is down)
    tolerance = 1e-8
    assert np.allclose(uvd_l, uv_l, atol=tolerance)
    # test write-out
    fout = str(tmp_path / "ex_miriad")
    uvd.write_miriad(fout, clobber=True)
    # assert equal to original miriad time
    uv2 = aipy_extracts.UV(fout)
    assert np.isclose(uv["time"], uv2["time"])
    assert np.isclose(uv["lst"], uv2["lst"], atol=tolerance)
Beispiel #5
0
 def func(x):
     return numpy.abs(
         uvutils.get_lst_for_time([JD_day + x], *lat_lon_alt)[0] - lst)
Beispiel #6
0
def empty_uvdata(nfreq,
                 ntimes,
                 ants,
                 antpairs=None,
                 pols=[
                     'xx',
                 ],
                 time_per_integ=10.7,
                 min_freq=0.1,
                 channel_bw=0.1 / 1024.,
                 instrument='hera_sim',
                 telescope_location=HERA_LOCATION,
                 telescope_lat_lon_alt=HERA_LAT_LON_ALT,
                 object_name='sim_data',
                 start_jd=2458119.5,
                 vis_units='uncalib'):
    """
    Create an empty UVData object with valid metadata and zeroed data arrays with the correct dimensions.

    Args:
        nfreq (int) : number of frequency channels.
        ntimes (int): number of LST bins.
        ant (dict): antenna positions.
            The key should be an integer antenna ID, and the value should be a tuple of (x, y, z) positions in the units
            required by UVData.antenna_positions (meters, position relative to telescope_location). Example::

                ants = {0 : (20., 20., 0.)}

        antpairs (list of len-2 tuples): List of baselines as antenna pair tuples, e.g. ``bls = [(1,2), (3,4)]``.
            All antennas must be in the ants dict.
        pols (list of str, optional): polarization strings.
        time_per_integ (float, optional): Time per integration.
        min_freq (float, optional): minimum frequency of the frequency array [GHz]
        channel_bw (float, optional): frequency channel bandwidth [GHz].
        instrument (str, optional): name of the instrument.
        telescope_location (list of float, optional): location of the telescope, in default UVData coordinate system.
            Expects a list of length 3.
        telescope_lat_lon_alt (tuple of float, optional): Latitude, longitude, and altitude of telescope, corresponding
            to the coordinates in telescope_location. Default: HERA_LAT_LON_ALT.
        object_name (str, optional): name of UVData object
        start_jd (float, optional): Julian date of the first time sample in the dataset.
        vis_units (str, optional): assumed units of the visibility data.
    
    Returns:
        :class:`pyuvdata.UVData`: A new UVData object containing valid metadata and blank (zeroed) arrays.
    """
    # Generate empty UVData object
    uvd = uv.UVData()

    # Basic time and freq. specs
    sim_freq = (min_freq + np.arange(nfreq) * channel_bw) * 1e9  # Hz
    sim_times = start_jd + np.arange(ntimes) * time_per_integ / SEC_PER_SDAY
    sim_pols = pols
    lat, lon, alt = telescope_lat_lon_alt
    sim_lsts = get_lst_for_time(sim_times, lat, lon, alt)

    # Basic telescope metadata
    uvd.instrument = instrument
    uvd.telescope_name = uvd.instrument
    uvd.telescope_location = np.array(telescope_location)
    uvd.telescope_lat_lon_alt = telescope_lat_lon_alt
    uvd.history = "Generated by hera_sim"
    uvd.object_name = object_name
    uvd.vis_units = vis_units

    # Fill-in array layout using dish positions
    nants = len(ants.keys())
    uvd.antenna_numbers = np.array([int(antid) for antid in ants.keys()],
                                   dtype=np.int)
    uvd.antenna_names = [str(antid) for antid in uvd.antenna_numbers]
    uvd.antenna_positions = np.zeros((nants, 3))
    uvd.Nants_data = nants
    uvd.Nants_telescope = nants

    # Populate antenna position table
    for i, antid in enumerate(ants.keys()):
        uvd.antenna_positions[i] = np.array(ants[antid])

    # Generate the antpairs if they are not given explicitly.
    antpairs, ant1, ant2 = _get_antpairs(ants, antpairs)

    defined_ants = ants.keys()
    ants_not_found = []
    for _ant in np.unique((ant1, ant2)):
        if _ant not in defined_ants:
            ants_not_found.append(_ant)
    if len(ants_not_found) > 0:
        raise KeyError("Baseline list contains antennas that were not "
                       "defined in the 'ants' dict: %s" % ants_not_found)

    # Convert to baseline integers
    bls = [uvd.antnums_to_baseline(*_antpair) for _antpair in antpairs]
    bls = np.unique(bls)

    # Convert back to ant1 and ant2 lists
    ant1, ant2 = list(zip(*[uvd.baseline_to_antnums(_bl) for _bl in bls]))

    # Add frequency and polarization arrays
    uvd.freq_array = sim_freq.reshape((1, sim_freq.size))
    uvd.polarization_array = np.array([polstr2num(_pol) for _pol in sim_pols],
                                      dtype=np.int)
    uvd.channel_width = sim_freq[1] - sim_freq[0]
    uvd.Nfreqs = sim_freq.size
    uvd.Nspws = 1
    uvd.Npols = len(sim_pols)

    # Generate LST array (for each LST: Nbls copy of LST)
    # and bls array (repeat bls list Ntimes times)
    bl_arr, lst_arr = np.meshgrid(np.array(bls), sim_lsts)
    uvd.baseline_array = bl_arr.flatten()
    uvd.lst_array = lst_arr.flatten()

    # Time array
    _, time_arr = np.meshgrid(np.array(bls), sim_times)
    uvd.time_array = time_arr.flatten()

    # Set antenna arrays (same shape as baseline_array)
    ant1_arr, _ = np.meshgrid(np.array(ant1), sim_lsts)
    ant2_arr, _ = np.meshgrid(np.array(ant2), sim_lsts)
    uvd.ant_1_array = ant1_arr.flatten()
    uvd.ant_2_array = ant2_arr.flatten()

    # Sets UVWs
    uvd.set_uvws_from_antenna_positions()

    # Populate array lengths
    uvd.Nbls = len(bls)
    uvd.Ntimes = sim_lsts.size
    uvd.Nblts = bl_arr.size

    # Initialise data, flag, and integration arrays
    uvd.data_array = np.zeros((uvd.Nblts, uvd.Nspws, uvd.Nfreqs, uvd.Npols),
                              dtype=np.complex64)
    uvd.flag_array = np.zeros((uvd.Nblts, uvd.Nspws, uvd.Nfreqs, uvd.Npols),
                              dtype=bool)
    uvd.nsample_array = np.ones((uvd.Nblts, uvd.Nspws, uvd.Nfreqs, uvd.Npols),
                                dtype=np.float32)
    uvd.spw_array = np.ones(1, dtype=np.int)
    uvd.integration_time = time_per_integ * np.ones(uvd.Nblts)  # per bl-time

    uvd.phase_type = 'drift'

    # Check validity and return
    uvd.check()
    return uvd