Beispiel #1
0
uv.Nbls = 1
uv.Ntimes = Ntimes
uv.spw_array = [0]
uv.Nfreqs = Nfreqs
uv.freq_array = freqs[np.newaxis, :]
uv.Nblts = uv.Ntimes * uv.Nbls
uv.ant_1_array = np.zeros(uv.Nblts, dtype=int)
uv.ant_2_array = np.ones(uv.Nblts, dtype=int)
uv.baseline_array = uv.antnums_to_baseline(uv.ant_1_array, uv.ant_2_array)
uv.time_array = time_arr
uv.Npols = 1
uv.polarization_array=np.array([1])
uv.Nants_telescope = 2
uv.Nants_data = 2
uv.antenna_positions = uvutils.ECEF_from_ENU(np.stack([ant1_enu, ant2_enu]), latitude, longitude, altitude)
uv.Nspws = 1
uv.antenna_numbers = np.array([0,1])
uv.antenna_names = ['ant0', 'ant1']
#uv.channel_width = np.ones(uv.Nblts) * np.diff(freqs)[0]
uv.channel_width = np.diff(freqs)[0]
uv.integration_time = np.ones(uv.Nblts) * np.diff(time_arr)[0] * 24 * 3600.  # Seconds
uv.uvw_array = np.tile(ant1_enu - ant2_enu, uv.Nblts).reshape(uv.Nblts, 3)
uv.history = 'Eorsky simulated'
uv.set_drift()
uv.telescope_name = 'Eorsky gaussian'
uv.instrument = 'simulator'
uv.object_name = 'zenith'
uv.vis_units = 'Jy'
uv.telescope_location_lat_lon_alt_degrees = (latitude, longitude, altitude)
uv.set_lsts_from_time_array()
uv.extra_keywords = {'bsq_int': beam_sq_int[0], 'skysig': sig, 'bm_fwhm' : fwhm, 'nside': Nside}
Beispiel #2
0
def apply_bda(
    uv, max_decorr, pre_fs_int_time, corr_fov_angle, max_time, corr_int_time=None
):
    """Apply baseline dependent averaging to a UVData object.

    For each baseline in the UVData object, the expected decorrelation from
    averaging in time is computed. Baselines are averaged together in powers-
    of-two until the specified level of decorrelation is reached (rounded down).

    Parameters
    ----------
    uv : UVData object
        The UVData object to apply BDA to. No changes are made to this object,
        and instead a copy is returned.
    max_decorr : float
        The maximum decorrelation fraction desired in the output object. Must
        be between 0 and 1.
    pre_fs_int_time : astropy Quantity
        The pre-finge-stopping integration time inside of the correlator. The
        quantity should be compatible with units of time.
    corr_fov_angle : astropy Angle
        The opening angle at which the maximum decorrelation is to be
        calculated. Because a priori it is not known in which direction the
        decorrelation will be largest, the expected decorrelation is computed in
        all 4 cardinal directions at `corr_fov_angle` degrees off of zenith,
        and the largest one is used. This is a "worst case scenario"
        decorrelation.
    max_time : astropy Quantity
        The maximum amount of time that spectra from different times should be
        combined for. The ultimate integration time for a given baseline will be
        for max_time or the integration time that is smaller than the specified
        decorrelation level, whichever is smaller. The quantity should be
        compatible with units of time.
    corr_int_time : astropy Quantity, optional
        The output time of the correlator. If not specified, the smallest
        integration_time in the UVData object is used. If specified, the
        quantity should be compatible with units of time.

    Returns
    -------
    uv2 : UVData object
        The UVData object with BDA applied.

    Raises
    ------
    ValueError
        This is raised if the input parameters are not the appropriate type or
        in the appropriate range. It is also raised if the input UVData object
        is not in drift mode (the BDA code does rephasing within an averaged
        set of baselines).
    AssertionError
        This is raised if the baselines of the UVData object are not time-
        ordered.
    """
    if not isinstance(uv, UVData):
        raise ValueError(
            "apply_bda must be passed a UVData object as its first argument"
        )
    if not isinstance(corr_fov_angle, Angle):
        raise ValueError(
            "corr_fov_angle must be an Angle object from astropy.coordinates"
        )
    if not isinstance(pre_fs_int_time, units.Quantity):
        raise ValueError("pre_fs_int_time must be an astropy.units.Quantity")
    try:
        pre_fs_int_time.to(units.s)
    except UnitConversionError:
        raise ValueError("pre_fs_int_time must be a Quantity with units of time")
    if (
        corr_fov_angle.to(units.deg).value < 0
        or corr_fov_angle.to(units.deg).value > 90
    ):
        raise ValueError("corr_fov_angle must be between 0 and 90 degrees")
    if max_decorr < 0 or max_decorr > 1:
        raise ValueError("max_decorr must be between 0 and 1")
    if not isinstance(max_time, units.Quantity):
        raise ValueError("max_time must be an astropy.units.Quantity")
    try:
        max_time.to(units.s)
    except UnitConversionError:
        raise ValueError("max_time must be a Quantity with units of time")
    if corr_int_time is None:
        # assume the correlator integration time is the smallest int_time of the
        # UVData object
        corr_int_time = np.unique(uv.integration_time)[0] * units.s
    else:
        if not isinstance(corr_int_time, units.Quantity):
            raise ValueError("corr_int_time must be an astropy.units.Quantity")
        try:
            corr_int_time.to(units.s)
        except UnitConversionError:
            raise ValueError("corr_int_time must be a Quantity with units of time")
    if uv.phase_type != "drift":
        raise ValueError("UVData object must be in drift mode to apply BDA")

    # get relevant bits of metadata
    freq = np.amax(uv.freq_array[0, :]) * units.Hz
    chan_width = uv.channel_width * units.Hz
    antpos_enu, ants = uv.get_ENU_antpos()
    lat, lon, alt = uv.telescope_location_lat_lon_alt
    antpos_ecef = uvutils.ECEF_from_ENU(antpos_enu, lat, lon, alt)
    telescope_location = EarthLocation.from_geocentric(
        uv.telescope_location[0],
        uv.telescope_location[1],
        uv.telescope_location[2],
        unit="m",
    )

    # make a new UVData object to put BDA baselines in
    uv2 = UVData()

    # copy over metadata
    uv2.Nbls = uv.Nbls
    uv2.Nfreqs = uv.Nfreqs
    uv2.Npols = uv.Npols
    uv2.vis_units = uv.vis_units
    uv2.Nspws = uv.Nspws
    uv2.spw_array = uv.spw_array
    uv2.freq_array = uv.freq_array
    uv2.polarization_array = uv.polarization_array
    uv2.channel_width = uv.channel_width
    uv2.object_name = uv.object_name
    uv2.telescope_name = uv.telescope_name
    uv2.instrument = uv.instrument
    uv2.telescope_location = uv.telescope_location
    history = uv.history + " Baseline dependent averaging applied."
    uv2.history = history
    uv2.Nants_data = uv.Nants_data
    uv2.Nants_telescope = uv.Nants_telescope
    uv2.antenna_names = uv.antenna_names
    uv2.antenna_numbers = uv.antenna_numbers
    uv2.x_orientation = uv.x_orientation
    uv2.extra_keywords = uv.extra_keywords
    uv2.antenna_positions = uv.antenna_positions
    uv2.antenna_diameters = uv.antenna_diameters
    uv2.gst0 = uv.gst0
    uv2.rdate = uv.rdate
    uv2.earth_omega = uv.earth_omega
    uv2.dut1 = uv.dut1
    uv2.timesys = uv.timesys
    uv2.uvplane_reference_time = uv.uvplane_reference_time

    # initialize place-keeping variables and Nblt-sized metadata
    start_index = 0
    uv2.Nblts = 0
    uv2.uvw_array = np.zeros_like(uv.uvw_array)
    uv2.time_array = np.zeros_like(uv.time_array)
    uv2.lst_array = np.zeros_like(uv.lst_array)
    uv2.ant_1_array = np.zeros_like(uv.ant_1_array)
    uv2.ant_2_array = np.zeros_like(uv.ant_2_array)
    uv2.baseline_array = np.zeros_like(uv.baseline_array)
    uv2.integration_time = np.zeros_like(uv.integration_time)
    uv2.data_array = np.zeros_like(uv.data_array)
    uv2.flag_array = np.zeros_like(uv.flag_array)
    uv2.nsample_array = np.zeros_like(uv.nsample_array)

    # iterate over baselines
    for key in uv.get_antpairs():
        print("averaging baseline ", key)
        ind1, ind2, indp = uv._key2inds(key)
        if len(ind2) != 0:
            raise AssertionError(
                "ind2 from _key2inds() is not 0--exiting. This should not happen, "
                "please contact the package maintainers."
            )
        data = uv._smart_slicing(
            uv.data_array, ind1, ind2, indp, squeeze="none", force_copy=True
        )
        flags = uv._smart_slicing(
            uv.flag_array, ind1, ind2, indp, squeeze="none", force_copy=True
        )
        nsamples = uv._smart_slicing(
            uv.nsample_array, ind1, ind2, indp, squeeze="none", force_copy=True
        )

        # get lx and ly for baseline
        ant1 = np.where(ants == key[0])[0][0]
        ant2 = np.where(ants == key[1])[0][0]
        x1, y1, z1 = antpos_ecef[ant1, :]
        x2, y2, z2 = antpos_ecef[ant2, :]
        lx = np.abs(x2 - x1) * units.m
        ly = np.abs(y2 - y1) * units.m

        # figure out how many time samples we can combine together
        if key[0] == key[1]:
            # autocorrelation--don't average
            n_two_foldings = 0
        else:
            n_two_foldings = dc.bda_compression_factor(
                max_decorr,
                freq,
                lx,
                ly,
                corr_fov_angle,
                chan_width,
                pre_fs_int_time,
                corr_int_time,
            )
        # convert from max_time to max_samples
        max_samples = (max_time / corr_int_time).to(units.dimensionless_unscaled)
        max_two_foldings = int(np.floor(np.log2(max_samples)))
        n_two_foldings = min(n_two_foldings, max_two_foldings)
        n_int = 2 ** (n_two_foldings)
        print("averaging {:d} time samples...".format(n_int))

        # figure out how many output samples we're going to have
        n_in = len(ind1)
        n_out = n_in // n_int + min(1, n_in % n_int)

        # get relevant metdata
        uvw_array = uv.uvw_array[ind1, :]
        times = uv.time_array[ind1]
        if not np.all(times == np.sort(times)):
            raise AssertionError(
                "times of uvdata object are not monotonically increasing; "
                "throwing our hands up"
            )
        lsts = uv.lst_array[ind1]
        int_time = uv.integration_time[ind1]

        # do the averaging
        input_shape = data.shape
        assert input_shape == (n_in, 1, uv.Nfreqs, uv.Npols)
        output_shape = (n_out, 1, uv.Nfreqs, uv.Npols)
        data_out = np.empty(output_shape, dtype=np.complex128)
        flags_out = np.empty(output_shape, dtype=np.bool_)
        nsamples_out = np.empty(output_shape, dtype=np.float32)
        uvws_out = np.empty((n_out, 3), dtype=np.float64)
        times_out = np.empty((n_out,), dtype=np.float64)
        lst_out = np.empty((n_out,), dtype=np.float64)
        int_time_out = np.empty((n_out,), dtype=np.float64)

        if n_out == n_in:
            # we don't need to average
            current_index = start_index + n_out
            uv2.data_array[start_index:current_index, :, :, :] = data
            uv2.flag_array[start_index:current_index, :, :, :] = flags
            uv2.nsample_array[start_index:current_index, :, :, :] = nsamples
            uv2.uvw_array[start_index:current_index, :] = uvw_array
            uv2.time_array[start_index:current_index] = times
            uv2.lst_array[start_index:current_index] = lsts
            uv2.integration_time[start_index:current_index] = int_time
            uv2.ant_1_array[start_index:current_index] = key[0]
            uv2.ant_2_array[start_index:current_index] = key[1]
            uv2.baseline_array[start_index:current_index] = uvutils.antnums_to_baseline(
                ant1, ant2, None
            )
            start_index = current_index

        else:
            # rats, we actually have to do work...

            # phase up the data along each chunk of times
            for i in range(n_out):
                # compute zenith of the desired output time
                i1 = i * n_int
                i2 = min((i + 1) * n_int, n_in)
                assert i2 - i1 > 0
                t0 = Time((times[i1] + times[i2 - 1]) / 2, scale="utc", format="jd")
                zenith_coord = SkyCoord(
                    alt=Angle(90 * units.deg),
                    az=Angle(0 * units.deg),
                    obstime=t0,
                    frame="altaz",
                    location=telescope_location,
                )
                obs_zenith_coord = zenith_coord.transform_to("icrs")
                zenith_ra = obs_zenith_coord.ra
                zenith_dec = obs_zenith_coord.dec

                # get data, flags, and nsamples of slices
                data_chunk = data[i1:i2, :, :, :]
                flags_chunk = flags[i1:i2, :, :, :]
                nsamples_chunk = nsamples[i1:i2, :, :, :]

                # actually phase now
                # compute new uvw coordinates
                icrs_coord = SkyCoord(
                    ra=zenith_ra, dec=zenith_dec, unit="radian", frame="icrs"
                )
                uvws = np.float64(uvw_array[i1:i2, :])
                itrs_telescope_location = SkyCoord(
                    x=uv.telescope_location[0] * units.m,
                    y=uv.telescope_location[1] * units.m,
                    z=uv.telescope_location[2] * units.m,
                    representation_type="cartesian",
                    frame="itrs",
                    obstime=t0,
                )
                itrs_lat_lon_alt = uv.telescope_location_lat_lon_alt

                frame_telescope_location = itrs_telescope_location.transform_to("icrs")

                frame_telescope_location.representation_type = "cartesian"

                uvw_ecef = uvutils.ECEF_from_ENU(uvws, *itrs_lat_lon_alt)

                itrs_uvw_coord = SkyCoord(
                    x=uvw_ecef[:, 0] * units.m,
                    y=uvw_ecef[:, 1] * units.m,
                    z=uvw_ecef[:, 2] * units.m,
                    representation_type="cartesian",
                    frame="itrs",
                    obstime=t0,
                )
                frame_uvw_coord = itrs_uvw_coord.transform_to("icrs")

                frame_rel_uvw = (
                    frame_uvw_coord.cartesian.get_xyz().value.T
                    - frame_telescope_location.cartesian.get_xyz().value
                )

                new_uvws = uvutils.phase_uvw(
                    icrs_coord.ra.rad, icrs_coord.dec.rad, frame_rel_uvw
                )

                # average these uvws together to get the "average" position in
                # the uv-plane
                avg_uvws = np.average(new_uvws, axis=0)

                # calculate and apply phasor
                w_lambda = (
                    new_uvws[:, 2].reshape((i2 - i1), 1)
                    / const.c.to("m/s").value
                    * uv.freq_array.reshape(1, uv.Nfreqs)
                )
                phs = np.exp(-1j * 2 * np.pi * w_lambda[:, None, :, None])
                data_chunk *= phs

                # sum data, propagate flag array, and adjusting nsample accordingly
                data_slice = np.sum(data_chunk, axis=0)
                flag_slice = np.sum(flags_chunk, axis=0)
                nsamples_slice = np.sum(nsamples_chunk, axis=0) / (i2 - i1)
                data_out[i, :, :, :] = data_slice
                flags_out[i, :, :, :] = flag_slice
                nsamples_out[i, :, :, :] = nsamples_slice

                # update metadata
                uvws_out[i, :] = avg_uvws
                times_out[i] = (times[i1] + times[i2 - 1]) / 2
                lst_out[i] = (lsts[i1] + lsts[i2 - 1]) / 2
                int_time_out[i] = np.average(int_time[i1:i2]) * (i2 - i1)

            # update data and metadata when we're done with this baseline
            current_index = start_index + n_out
            uv2.data_array[start_index:current_index, :, :, :] = data_out
            uv2.flag_array[start_index:current_index, :, :, :] = flags_out
            uv2.nsample_array[start_index:current_index, :, :, :] = nsamples_out
            uv2.uvw_array[start_index:current_index, :] = uvws_out
            uv2.time_array[start_index:current_index] = times_out
            uv2.lst_array[start_index:current_index] = lst_out
            uv2.integration_time[start_index:current_index] = int_time_out
            uv2.ant_1_array[start_index:current_index] = key[0]
            uv2.ant_2_array[start_index:current_index] = key[1]
            uv2.baseline_array[start_index:current_index] = uvutils.antnums_to_baseline(
                ant1, ant2, None
            )
            start_index = current_index

    # clean up -- shorten all arrays to actually be size nblts
    nblts = start_index
    uv2.Nblts = nblts
    uv2.data_array = uv2.data_array[:nblts, :, :, :]
    uv2.flag_array = uv2.flag_array[:nblts, :, :, :]
    uv2.nsample_array = uv2.nsample_array[:nblts, :, :, :]
    uv2.uvw_array = uv2.uvw_array[:nblts, :]
    uv2.time_array = uv2.time_array[:nblts]
    uv2.lst_array = uv2.lst_array[:nblts]
    uv2.integration_time = uv2.integration_time[:nblts]
    uv2.ant_1_array = uv2.ant_1_array[:nblts]
    uv2.ant_2_array = uv2.ant_2_array[:nblts]
    uv2.baseline_array = uv2.baseline_array[:nblts]
    uv2.Ntimes = len(np.unique(uv2.time_array))

    # set phasing info
    uv2.phase_type = "phased"
    uv2.phase_center_ra = zenith_ra.rad
    uv2.phase_center_dec = zenith_dec.rad
    uv2.phase_center_frame = 2000.0

    # fix up to correct old phasing method
    uv2.phase(zenith_ra.rad, zenith_dec.rad, epoch="J2000", fix_old_proj=True)

    # run a check
    uv2.check()

    return uv2
Beispiel #3
0
def initialize_uvdata(uvtask_list,
                      source_list_name,
                      uvdata_file=None,
                      obs_param_file=None,
                      telescope_config_file=None,
                      antenna_location_file=None):
    """
    Initialize an empty uvdata object to fill with simulation.

    Args:
        uvtask_list: List of uvtasks to simulate.
        source_list_name: Name of source list file or mock catalog.
        uvdata_file: Name of input UVData file or None if initializing from
            config files.
        obs_param_file: Name of observation parameter config file or None if
            initializing from a UVData file.
        telescope_config_file: Name of telescope config file or None if
            initializing from a UVData file.
        antenna_location_file: Name of antenna location file or None if
            initializing from a UVData file.
    """

    if not isinstance(source_list_name, str):
        raise ValueError('source_list_name must be a string')

    if uvdata_file is not None:
        if not isinstance(uvdata_file, str):
            raise ValueError('uvdata_file must be a string')
        if (obs_param_file is not None or telescope_config_file is not None
                or antenna_location_file is not None):
            raise ValueError('If initializing from a uvdata_file, none of '
                             'obs_param_file, telescope_config_file or '
                             'antenna_location_file can be set.')
    elif (obs_param_file is None or telescope_config_file is None
          or antenna_location_file is None):
        if not isinstance(obs_param_file, str):
            raise ValueError('obs_param_file must be a string')
        if not isinstance(telescope_config_file, str):
            raise ValueError('telescope_config_file must be a string')
        if not isinstance(antenna_location_file, str):
            raise ValueError('antenna_location_file must be a string')
        raise ValueError('If not initializing from a uvdata_file, all of '
                         'obs_param_file, telescope_config_file or '
                         'antenna_location_file must be set.')

    # Version string to add to history
    history = get_version_string()

    history += ' Sources from source list: ' + source_list_name + '.'

    if uvdata_file is not None:
        history += ' Based on UVData file: ' + uvdata_file + '.'
    else:
        history += (' Based on config files: ' + obs_param_file + ', ' +
                    telescope_config_file + ', ' + antenna_location_file)

    history += ' Npus = ' + str(Npus) + '.'

    task_freqs = []
    task_bls = []
    task_times = []
    task_antnames = []
    task_antnums = []
    task_antpos = []
    task_uvw = []
    ant_1_array = []
    ant_2_array = []
    telescope_name = uvtask_list[0].telescope.telescope_name
    telescope_location = uvtask_list[0].telescope.telescope_location.geocentric

    source_0 = uvtask_list[0].source
    freq_0 = uvtask_list[0].freq
    for task in uvtask_list:
        if not task.source == source_0:
            continue
        task_freqs.append(task.freq)

        if task.freq == freq_0:
            task_bls.append(task.baseline)
            task_times.append(task.time)
            task_antnames.append(task.baseline.antenna1.name)
            task_antnames.append(task.baseline.antenna2.name)
            ant_1_array.append(task.baseline.antenna1.number)
            ant_2_array.append(task.baseline.antenna2.number)
            task_antnums.append(task.baseline.antenna1.number)
            task_antnums.append(task.baseline.antenna2.number)
            task_antpos.append(task.baseline.antenna1.pos_enu)
            task_antpos.append(task.baseline.antenna2.pos_enu)
            task_uvw.append(task.baseline.uvw)

    antnames, ant_indices = np.unique(task_antnames, return_index=True)
    task_antnums = np.array(task_antnums)
    task_antpos = np.array(task_antpos)
    antnums = task_antnums[ant_indices]
    antpos = task_antpos[ant_indices]

    freqs = np.unique(task_freqs)

    uv_obj = UVData()

    # add pyuvdata version info
    history += uv_obj.pyuvdata_version_str

    uv_obj.telescope_name = telescope_name
    uv_obj.telescope_location = np.array(
        [tl.to('m').value for tl in telescope_location])
    uv_obj.instrument = telescope_name
    uv_obj.Nfreqs = freqs.size
    uv_obj.Ntimes = np.unique(task_times).size
    uv_obj.Nants_data = antnames.size
    uv_obj.Nants_telescope = uv_obj.Nants_data
    uv_obj.Nblts = len(ant_1_array)

    uv_obj.antenna_names = antnames.tolist()
    uv_obj.antenna_numbers = antnums
    antpos_ecef = uvutils.ECEF_from_ENU(
        antpos, *
        uv_obj.telescope_location_lat_lon_alt) - uv_obj.telescope_location
    uv_obj.antenna_positions = antpos_ecef
    uv_obj.ant_1_array = np.array(ant_1_array)
    uv_obj.ant_2_array = np.array(ant_2_array)
    uv_obj.time_array = np.array(task_times)
    uv_obj.uvw_array = np.array(task_uvw)
    uv_obj.baseline_array = uv_obj.antnums_to_baseline(ant_1_array,
                                                       ant_2_array)
    uv_obj.Nbls = np.unique(uv_obj.baseline_array).size
    if uv_obj.Nfreqs == 1:
        uv_obj.channel_width = 1.  # Hz
    else:
        uv_obj.channel_width = np.diff(freqs)[0]

    if uv_obj.Ntimes == 1:
        uv_obj.integration_time = np.ones_like(uv_obj.time_array,
                                               dtype=np.float64)  # Second
    else:
        # Note: currently only support a constant spacing of times
        uv_obj.integration_time = (
            np.ones_like(uv_obj.time_array, dtype=np.float64) *
            np.diff(np.unique(task_times))[0])
    uv_obj.set_lsts_from_time_array()
    uv_obj.zenith_ra = uv_obj.lst_array
    uv_obj.zenith_dec = np.repeat(uv_obj.telescope_location_lat_lon_alt[0],
                                  uv_obj.Nblts)  # Latitude
    uv_obj.object_name = 'zenith'
    uv_obj.set_drift()
    uv_obj.vis_units = 'Jy'
    uv_obj.polarization_array = np.array([-5, -6, -7, -8])
    uv_obj.spw_array = np.array([0])
    uv_obj.freq_array = np.array([freqs])

    uv_obj.Nspws = uv_obj.spw_array.size
    uv_obj.Npols = uv_obj.polarization_array.size

    uv_obj.data_array = np.zeros(
        (uv_obj.Nblts, uv_obj.Nspws, uv_obj.Nfreqs, uv_obj.Npols),
        dtype=np.complex)
    uv_obj.flag_array = np.zeros(
        (uv_obj.Nblts, uv_obj.Nspws, uv_obj.Nfreqs, uv_obj.Npols), dtype=bool)
    uv_obj.nsample_array = np.ones_like(uv_obj.data_array, dtype=float)
    uv_obj.history = history

    uv_obj.check()

    return uv_obj
Beispiel #4
0
# Run simulation
# ---------------------------

print("Running simulation")
sys.stdout.flush()
visibs, time_array, baseline_inds = obs.make_visibilities(shell0, Nprocs=Nprocs)

uv_obj.time_array = time_array
uv_obj.set_lsts_from_time_array()
uv_obj.baseline_array = bl_array[baseline_inds]
uv_obj.ant_1_array, uv_obj.ant_2_array = uv_obj.baseline_to_antnums(uv_obj.baseline_array)

uv_obj.spw_array = np.array([0])
uv_obj.Npols = 1
uv_obj.polarization_array=np.array([1])
uv_obj.Nspws = 1
uv_obj.set_uvws_from_antenna_positions()
uv_obj.channel_width = np.diff(freqs)[0]
uv_obj.integration_time = np.ones(uv_obj.Nblts) * np.diff(time_arr)[0] * 24 * 3600.  # Seconds
uv_obj.history = 'eorsky'
uv_obj.set_drift()
uv_obj.telescope_name = 'eorsky'
uv_obj.instrument = 'simulator'
uv_obj.object_name = 'zenith'
uv_obj.vis_units = 'Jy'

if sjob_id is None:
    sjob_id = ''

if beam_type == 'gaussian':
    fwhm = beam_attr['sigma'] * 2.355
Beispiel #5
0
    uvfile = or_xx_files[0]

    uvd = UVData()
    uvd.read_miriad(uvfile)

    # create uvdata object
    uvd = UVData()

    uvd.Nants_telescope = self.Nants
    uvd.Nants_data = len(np.unique(bl_array))
    uvd.Nbls = Nbls
    uvd.Ntimes = Ntimes
    uvd.Nblts = Nbls * Ntimes
    uvd.Nfreqs = self.Nfreqs
    uvd.Npols = self.Nxpols
    uvd.Nspws = 1
    uvd.antenna_numbers = self.ant_nums
    uvd.antenna_names = np.array(self.ant_nums, dtype=str)
    uvd.ant_1_array = np.concatenate(
        [map(lambda x: x[0], bl_array) for i in range(Ntimes)])
    uvd.ant_2_array = np.concatenate(
        [map(lambda x: x[1], bl_array) for i in range(Ntimes)])
    uvd.baseline_array = np.concatenate(
        [np.arange(Nbls) for i in range(Ntimes)])
    uvd.freq_array = (self.freqs * 1e6).reshape(1, -1)
    uvd.time_array = np.repeat(np.array(JD_array)[:, np.newaxis], Nbls,
                               axis=1).ravel()
    uvd.channel_width = (self.freqs * 1e6)[1] - (self.freqs * 1e6)[0]
    uvd.data_array = self.vis_data.reshape(uvd.Nblts, 1, self.Nfreqs,
                                           self.Nxpols)
    uvd.flag_array = np.ones_like(uvd.data_array, dtype=np.bool)
Beispiel #6
0
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
Beispiel #7
0
def fake_data_generator():
    """Generate a fake dataset as a module-level fixture."""
    # generate a fake data file for testing BDA application
    uvd = UVData()
    t0 = 2459000.0
    dt = (2 * units.s).to(units.day)
    t1 = t0 + dt.value
    t2 = t0 + 2 * dt.value
    # define baseline-time spacing
    uvd.ant_1_array = np.asarray([0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=np.int_)
    uvd.ant_2_array = np.asarray([0, 1, 2, 0, 1, 2, 0, 1, 2], dtype=np.int_)
    uvd.time_array = np.asarray([t0, t0, t0, t1, t1, t1, t2, t2, t2],
                                dtype=np.float64)
    uvd.Ntimes = 3
    uvd.Nbls = 3
    uvd.Nblts = uvd.Ntimes * uvd.Nbls

    # define frequency array
    nfreqs = 1024
    freq_array = np.linspace(50e6, 250e6, num=nfreqs)
    uvd.freq_array = freq_array[np.newaxis, :]
    uvd.spw_array = [0]
    uvd.Nfreqs = nfreqs
    uvd.Nspws = 1

    # define polarization array
    uvd.polarization_array = [-5]
    uvd.Npols = 1

    # make random data for data array
    data_shape = (uvd.Nblts, 1, uvd.Nfreqs, uvd.Npols)
    uvd.data_array = np.zeros(data_shape, dtype=np.complex128)
    rng = default_rng()
    uvd.data_array += rng.standard_normal(data_shape)
    uvd.data_array += 1j * rng.standard_normal(data_shape)
    uvd.flag_array = np.zeros_like(uvd.data_array, dtype=np.bool_)
    uvd.nsample_array = np.ones_like(uvd.data_array, dtype=np.float32)

    # set telescope and antenna positions
    hera_telescope = pyuvdata.telescopes.get_telescope("HERA")
    uvd.telescope_location_lat_lon_alt = hera_telescope.telescope_location_lat_lon_alt
    antpos0 = np.asarray([0, 0, 0], dtype=np.float64)
    antpos1 = np.asarray([14, 0, 0], dtype=np.float64)
    antpos2 = np.asarray([28, 0, 0], dtype=np.float64)
    antpos_enu = np.vstack((antpos0, antpos1, antpos2))
    antpos_xyz = uvutils.ECEF_from_ENU(antpos_enu,
                                       *uvd.telescope_location_lat_lon_alt)
    uvd.antenna_positions = antpos_xyz - uvd.telescope_location

    uvw_array = np.zeros((uvd.Nblts, 3), dtype=np.float64)
    uvw_array[::3, :] = antpos0 - antpos0
    uvw_array[1::3, :] = antpos1 - antpos0
    uvw_array[2::3, :] = antpos2 - antpos0
    uvd.uvw_array = uvw_array
    uvd.antenna_numbers = np.asarray([0, 1, 2], dtype=np.int_)
    uvd.antenna_names = np.asarray(["H0", "H1", "H2"], dtype=np.str_)
    uvd.Nants_data = 3
    uvd.Nants_telescope = 3

    # set other metadata
    uvd.vis_units = "uncalib"
    uvd.channel_width = 5e4  # 50 kHz
    uvd.phase_type = "drift"
    uvd.baseline_array = uvd.antnums_to_baseline(uvd.ant_1_array,
                                                 uvd.ant_2_array)
    uvd.history = "BDA test file"
    uvd.instrument = "HERA"
    uvd.telescope_name = "HERA"
    uvd.object_name = "zenith"
    uvd.integration_time = 2 * np.ones_like(uvd.baseline_array,
                                            dtype=np.float64)
    uvd.set_lsts_from_time_array()

    # run a check
    uvd.check()

    yield uvd

    # clean up when done
    del uvd

    return
Beispiel #8
0
def uvdata_from_sim_data(
    array_lat,
    array_lon,
    array_height,
    jd_axis,
    nu_axis,
    r_axis,
    ant_pairs,
    V_sim,
    integration_time="derived",
    channel_width="derived",
    antenna_numbers="derived",
    antenna_names="derived",
    instrument="left blank by user",
    telescope_name="left blank by user",
    history="left blank by user",
    object_name="left blank by user",
):

    HERA_LAT = array_lat
    HERA_LON = array_lon
    HERA_HEIGHT = array_height

    HERA_LAT_LON_ALT = (HERA_LAT, HERA_LON, HERA_HEIGHT)
    HERA_LOC = coord.EarthLocation(
        lat=HERA_LAT * units.rad,
        lon=HERA_LON * units.rad,
        height=HERA_HEIGHT * units.meter,
    )

    jd_obj = Time(jd_axis, format="jd", location=HERA_LOC)
    lst_axis = jd_obj.sidereal_time("apparent").radian
    if integration_time == "derived":
        del_jd = jd_obj[1] - jd_obj[0]
        integration_time = del_jd.sec

    uvd = UVData()

    uvd.telescope_location = HERA_LOC.value
    uvd.telescope_location_lat_lon_alt = HERA_LAT_LON_ALT

    if antenna_numbers == "derived":
        uvd.antenna_numbers = np.arange(r_axis.shape[0], dtype=np.int64)

        ant_num_pairs = ant_pairs

    else:
        uvd.antenna_numbers = antenna_numbers

        ant_num_pairs = np.array([(antenna_numbers[ap[0]],
                                   antenna_numbers[ap[1]])
                                  for ap in ant_pairs])

    if antenna_names == "derived":
        uvd.antenna_names = [str(ant_ind) for ant_ind in uvd.antenna_numbers]
    else:
        uvd.antenna_names = antenna_names

    ant_pos_ECEF = pyuvdata.utils.ECEF_from_ENU(r_axis, HERA_LOC.lat.rad,
                                                HERA_LOC.lon.rad,
                                                HERA_LOC.height.value)
    uvd.antenna_positions = ant_pos_ECEF - uvd.telescope_location

    bls = [
        uvd.antnums_to_baseline(ant_num_pair[0], ant_num_pair[1])
        for ant_num_pair in ant_num_pairs
    ]

    uvd.freq_array = nu_axis.reshape((1, nu_axis.size))

    pols = ["xx", "yy", "xy", "yx"]
    uvd.polarization_array = np.array(
        [polstr2num(pol_str) for pol_str in pols])

    uvd.x_orientation = "east"

    if channel_width == "derived":
        uvd.channel_width = nu_axis[1] - nu_axis[0]
    else:
        uvd.channel_width = channel_width

    uvd.Nfreqs = nu_axis.size
    uvd.Nspws = 1
    uvd.Npols = len(pols)

    bl_arr, lst_arr = np.meshgrid(np.array(bls), lst_axis)
    uvd.baseline_array = bl_arr.flatten()
    uvd.lst_array = lst_arr.flatten()

    _, time_arr = np.meshgrid(np.array(bls), jd_axis)
    uvd.time_array = time_arr.flatten()

    ant1_arr, _ = np.meshgrid(ant_num_pairs[:, 0], lst_axis)
    ant2_arr, _ = np.meshgrid(ant_num_pairs[:, 1], lst_axis)
    uvd.ant_1_array = ant1_arr.flatten()
    uvd.ant_2_array = ant2_arr.flatten()

    # Nants_data might be less than r_axis.shape[0] for redundant arrays
    uvd.Nants_data = len(
        np.unique(np.r_[ant1_arr.flatten(),
                        ant2_arr.flatten()]))
    uvd.Nants_telescope = r_axis.shape[0]

    uvd.set_uvws_from_antenna_positions()

    uvd.Nbls = len(bls)
    uvd.Ntimes = lst_axis.size
    uvd.Nblts = bl_arr.size

    uvd.data_array = np.zeros((uvd.Nblts, uvd.Nspws, uvd.Nfreqs, uvd.Npols),
                              dtype=np.complex128)

    uvd.flag_array = np.zeros_like(uvd.data_array, dtype=np.bool)
    uvd.nsample_array = np.ones((uvd.Nblts, uvd.Nspws, uvd.Nfreqs, uvd.Npols),
                                dtype=np.float64)
    uvd.spw_array = np.ones(1, dtype=np.int64)
    uvd.integration_time = integration_time * np.ones(uvd.Nblts)

    uvd.phase_type = "drift"

    # (0,0) <-> 'xx' <-> East-East, etc.
    # matches order of uvd.polarization_array
    pol_map = {(0, 0): 0, (1, 1): 1, (0, 1): 2, (1, 0): 3}

    for i_a in range(2):
        for i_b in range(2):
            i_p = pol_map[(i_a, i_b)]

            for k in range(ant_num_pairs.shape[0]):
                a_i, a_j = ant_num_pairs[k]
                bl_num = uvd.antnums_to_baseline(a_i, a_j)
                bl_ind = np.where(uvd.baseline_array == bl_num)[0]

                uvd.data_array[bl_ind, 0, :, i_p] = np.copy(V_sim[:, :, k, i_a,
                                                                  i_b])

    uvd.vis_units = "Jy"

    uvd.instrument = instrument
    uvd.telescope_name = telescope_name
    uvd.history = history
    uvd.object_name = object_name

    uvd.check()

    return uvd
Beispiel #9
0
                    logger.info('Getting baseline pair: (%d, %d)..' % (a1, a2))
                    times.append(time.time())
                    if a1 == a2:
                        bram.imag = 0
                        bram.real = bram.real / float(
                            feng.corr.acc_len * feng.corr.spec_per_acc)
                    else:
                        bram = bram / float(
                            feng.corr.acc_len * feng.corr.spec_per_acc)
                    c.append(bram)
                poco.append(np.transpose(c))

            # Write output to pyuvdata file
            data = UVData()
            data.Nfreqs = len(fqs)
            data.Nspws = 1
            data.Npols = 1
            data.Nbls = len(bls)
            data.Ntimes = len(times)
            data.Nblts = data.Ntimes

            # Init flag array with no flags
            data.flag_array = np.empty(
                (data.Nblts, data.Nspws, data.Nfreqs, data.Npols), dtype=bool)
            data.flag_array[:] = False

            # Init nsamples array with  unity weights
            data.nsample_array = np.ones(
                (data.Nblts, data.Nspws, data.Nfreqs, data.Npols), dtype=float)

            # Create frequency array
Beispiel #10
0
    def sim_obs(self,
                bl_array,
                JD_array,
                pool=None,
                write_miriad=False,
                fname=None,
                clobber=False,
                one_beam_model=True,
                interp=True,
                Tnoise=None,
                fast_noise=False):
        """
		Simulate a visibility observation of the sky

		Input:
		------
		bl_array : list, shape=(Nbls, 2), entry_format=tuple(int, int)
		    list of baselines (antenna pairs)
		    in (ant1, ant2) with type(ant1) == int

		JD_array : list, shape=(Ntimes,), dtype=float
			list of Julian Dates for observations
    	"""
        # get array info
        Nbls = len(bl_array)
        str_bls = [(str(x[0]), str(x[1])) for x in bl_array]
        Ntimes = len(JD_array)
        rel_ants = np.unique(np.concatenate(bl_array))  # relevant antennas
        rel_ant2ind = OrderedDict(
            zip(np.array(rel_ants, str), np.arange(len(rel_ants))))

        # get antenna indices
        ant_inds = map(lambda x: self.ant2ind[str(x)], rel_ants)

        # get antenna positions for each baseline
        ant1_pos = np.array(map(lambda x: self.ant_pos[x[0]], str_bls))
        ant2_pos = np.array(map(lambda x: self.ant_pos[x[1]], str_bls))

        # get vector in u-v plane
        wavelengths = 2.9979e8 / (self.freqs * 1e6)
        self.uv_vecs = (ant2_pos - ant1_pos).reshape(Nbls, 3, -1) / wavelengths

        # Get direction unit vector, s-hat
        x, y, z = hp.pix2vec(self.beam_nside, np.arange(self.beam_npix))
        self.s_hat = np.array([y, x, z])

        # get phase map in topocentric frame (sqrt of full phase term)
        self.phase = np.exp(-1j * np.pi *
                            np.einsum('ijk,jl->ikl', self.uv_vecs, self.s_hat))

        # build beams for each antenna in topocentric coordinates
        self.build_beams(ant_inds=ant_inds, one_beam_model=one_beam_model)

        # create phase and beam product maps (Npol, Nbl, Nfreqs, Npix)
        self.beam_phs = self.ant_beam_models.reshape(
            self.Npols, -1, self.Nfreqs, self.beam_npix) * self.phase

        # loop over JDs
        self.vis_data = []
        for jd in JD_array:

            # map through each antenna and project polarized, multi-frequency beam model onto sky
            if one_beam_model == True:
                self.proj_beam_phs = self.project_beams(
                    jd,
                    self.sky_theta,
                    self.sky_phi,
                    beam_models=self.beam_phs,
                    output=True,
                    interp=interp)

            else:
                #proj_ant_beam_models = self.project_beams(JD, self.sky_theta, self.sky_phi,
                #beam_models=np.array(map(lambda x: self.ant_beam_models[str(x)], self.ant_nums)), output=True)
                self.proj_beam_phs = self.project_beams(
                    jd,
                    self.sky_theta,
                    self.sky_phi,
                    beam_models=self.beam_phs,
                    output=True,
                    interp=interp)

            # calculate visibility
            if pool is None:
                M = map
            else:
                M = pool.map

            # add noise
            if Tnoise is None or fast_noise is True:
                sky_models = self.sky_models
            else:
                sky_models = self.sky_models + self.generate_noise_map(
                    Tnoise, self.sky_models.shape)

            if one_beam_model is True:
                if self.onepol is True:
                    vis = np.einsum("ijkl, ikl -> ijk", self.proj_beam_phs**2,
                                    sky_models)
                else:
                    vis = np.einsum("ijkl, imkl, mjkl -> imjk",
                                    self.proj_beam_phs, sky_models,
                                    self.proj_beam_phs)
            else:
                vis = np.array(
                    map(
                        lambda x: np.einsum(
                            "ijk, jk, ljk -> ilj", self.proj_beam_phs[
                                rel_ant2ind[x[1][0]]], sky_models, self.
                            proj_beam_phs[rel_ant2ind[x[1][1]]]),
                        enumerate(str_bls)))

            self.vis_data.append(vis)

        if self.onepol is True:
            self.vis_data = np.moveaxis(np.array(self.vis_data), 0, 2)
        else:
            self.vis_data = np.moveaxis(np.array(self.vis_data), 0, 3)

        # normalize by the effective-beam solid angle
        if one_beam_model == True:
            self.ant_beam_sa = np.repeat(
                np.einsum('ijk,ijk->ij', self.ant_beam_models,
                          self.ant_beam_models)[:, np.newaxis, :], Nbls, 1)
        else:
            self.ant_beam_sa = np.array(
                map(
                    lambda x: np.einsum(
                        'ijk,ljk->ilj', self.proj_ant_beam_models[rel_ant2ind[
                            x[1][0]]], self.proj_ant_beam_models[rel_ant2ind[x[
                                1][1]]]), enumerate(str_bls)))
        if self.onepol is True:
            self.vis_data /= self.ant_beam_sa[:, :, np.newaxis, :]
            self.vis_data_shape = "(1, Nbls, Ntimes, Nfreqs)"
        else:
            self.vis_data /= self.ant_beam_sa[:, :, :, np.newaxis, :]
            self.vis_data_shape = "(2, 2, Nbls, Ntimes, Nfreqs)"

        if fast_noise is True and Tnoise is not None:
            self.vis_data += self.generate_vis_noise(
                Tnoise,
                self.freqs * 1e6,
                self.ant_beam_sa.squeeze(),
                self.vis_data.shape,
                bandwidth=self.bandwidth * 1e6,
                int_time=10.7)

        # write to file
        if write_miriad == True:

            # create uvdata object
            uvd = UVData()

            uvd.Nants_telescope = self.Nants
            uvd.Nants_data = len(np.unique(bl_array))
            uvd.Nbls = Nbls
            uvd.Ntimes = Ntimes
            uvd.Nblts = Nbls * Ntimes
            uvd.Nfreqs = self.Nfreqs
            uvd.Npols = self.Nxpols
            uvd.Nspws = 1
            uvd.antenna_numbers = self.ant_nums
            uvd.antenna_names = np.array(self.ant_nums, dtype=str)
            uvd.ant_1_array = np.concatenate(
                [map(lambda x: x[0], bl_array) for i in range(Ntimes)])
            uvd.ant_2_array = np.concatenate(
                [map(lambda x: x[1], bl_array) for i in range(Ntimes)])
            uvd.baseline_array = np.concatenate(
                [np.arange(Nbls) for i in range(Ntimes)])
            uvd.freq_array = (self.freqs * 1e6).reshape(1, -1)
            uvd.time_array = np.repeat(np.array(JD_array)[:, np.newaxis],
                                       Nbls,
                                       axis=1).ravel()
            uvd.channel_width = (self.freqs * 1e6)[1] - (self.freqs * 1e6)[0]
            uvd.data_array = self.vis_data.reshape(uvd.Nblts, 1, self.Nfreqs,
                                                   self.Nxpols)
            uvd.flag_array = np.ones_like(uvd.data_array, dtype=np.bool)
            uvd.history = " "
            uvd.instrument = " "
            uvd.integration_time = 10.7
            uvd.lst_array = np.repeat(np.array(
                map(lambda x: self.JD2LST(self.loc, x), JD_array))[:,
                                                                   np.newaxis],
                                      Nbls,
                                      axis=1).ravel()
            uvd.nsample_array = np.ones_like(uvd.data_array, dtype=np.float)
            uvd.object_name = ""
            uvd.phase_type = "drift"
            uvd.polarization_array = np.array(
                map(lambda x: {
                    "XX": -5,
                    "YY": -6,
                    "XY": -7,
                    "YX": -8
                }[x], self.xpols))
            uvd.spw_array = np.array([0])
            uvd.telescope_location = np.array([
                6378137. * np.cos(self.loc.lon) * np.cos(self.loc.lat),
                6378137. * np.sin(self.loc.lon) * np.cos(self.loc.lat),
                6378137. * np.sin(self.loc.lat)
            ])
            uvd.telescope_name = " "
            uvd.uvw_array = np.ones((uvd.Nblts, 3))
            uvd.vis_units = "Jy"
            zen_dec, zen_ra = self.loc.radec_of(0, np.pi / 2)
            uvd.zenith_dec = np.ones(uvd.Nblts) * zen_dec
            uvd.zenith_ra = np.ones(uvd.Nblts) * zen_ra

            uvd.write_miriad(fname, clobber=clobber)