def create_configuration_from_file(antfile: str, location: EarthLocation = None,
                                   mount: str = 'altaz',
                                   names: str = "%d", frame: str = 'local',
                                   diameter=35.0,
                                   rmax=None, name='') -> Configuration:
    """ Define from a file

    :param names: Antenna names
    :param antfile: Antenna file name
    :param location:
    :param mount: mount type: 'altaz', 'xy'
    :param frame: 'local' | 'global'
    :param diameter: Effective diameter of station or antenna
    :return: Configuration
    """
    antxyz = numpy.genfromtxt(antfile, delimiter=",")
    assert antxyz.shape[1] == 3, ("Antenna array has wrong shape %s" % antxyz.shape)
    if frame == 'local':
        latitude = location.geodetic[1].to(u.rad).value
        antxyz = xyz_at_latitude(antxyz, latitude)
    if rmax is not None:
        lantxyz = antxyz - numpy.average(antxyz, axis=0)
        r = numpy.sqrt(lantxyz[:, 0] ** 2 + lantxyz[:, 1] ** 2 + lantxyz[:, 2] ** 2)
        antxyz = antxyz[r < rmax]
        log.debug('create_configuration_from_file: Maximum radius %.1f m includes %d antennas/stations' %
                  (rmax, antxyz.shape[0]))
    
    nants = antxyz.shape[0]
    anames = [names % ant for ant in range(nants)]
    mounts = numpy.repeat(mount, nants)
    fc = Configuration(location=location, names=anames, mount=mounts, xyz=antxyz, frame=frame,
                       diameter=diameter, name=name)
    return fc
def create_LOFAR_configuration(antfile: str,
                               location,
                               rmax=1e6) -> Configuration:
    """ Define from the LOFAR configuration file

    :param antfile:
    :return: Configuration
    """
    antxyz = numpy.genfromtxt(antfile,
                              skip_header=2,
                              usecols=[1, 2, 3],
                              delimiter=",")
    nants = antxyz.shape[0]
    assert antxyz.shape[
        1] == 3, "Antenna array has wrong shape %s" % antxyz.shape
    anames = numpy.genfromtxt(antfile,
                              dtype='str',
                              skip_header=2,
                              usecols=[0],
                              delimiter=",")
    mounts = numpy.repeat('XY', nants)
    diameters = numpy.repeat(35.0, nants)

    antxyz, diameters, mounts, anames = limit_rmax(antxyz, diameters, anames,
                                                   mounts, rmax)

    fc = Configuration(location=location,
                       names=anames,
                       mount=mounts,
                       xyz=antxyz,
                       diameter=diameters,
                       name='LOFAR')
    return fc
예제 #3
0
def create_LOFAR_configuration(antfile: str) -> Configuration:
    """ Define from the LOFAR configuration file

    :param antfile:
    :return: Configuration
    """
    antxyz = numpy.genfromtxt(antfile,
                              skip_header=2,
                              usecols=[1, 2, 3],
                              delimiter=",")
    nants = antxyz.shape[0]
    assert antxyz.shape[
        1] == 3, "Antenna array has wrong shape %s" % antxyz.shape
    anames = numpy.genfromtxt(antfile,
                              dtype='str',
                              skip_header=2,
                              usecols=[0],
                              delimiter=",")
    mounts = numpy.repeat('XY', nants)
    location = EarthLocation(x=[3826923.9] * u.m,
                             y=[460915.1] * u.m,
                             z=[5064643.2] * u.m)
    fc = Configuration(location=location,
                       names=anames,
                       mount=mounts,
                       xyz=antxyz,
                       frame='global',
                       diameter=35.0,
                       name='LOFAR')
    return fc
def convert_configuration_from_hdf(f):
    """ Extyract configuration from HDF

    :param f:
    :return:
    """
    cf = f['configuration']

    assert cf.attrs[
        'ARL_data_model'] == "Configuration", "%s is a Configuration" % cf.attrs[
            'ARL_data_model']

    name = cf.attrs['name']
    location = convert_earthlocation_from_string(cf.attrs['location'])
    frame = cf.attrs['frame']
    receptor_frame = cf.attrs['receptor_frame']

    xyz = cf['configuration/xyz']
    diameter = cf['configuration/diameter']
    names = [str(n) for n in cf['configuration/names']]
    mount = [str(m) for m in cf['configuration/mount']]
    return Configuration(name=name,
                         location=location,
                         frame=frame,
                         receptor_frame=receptor_frame,
                         xyz=xyz,
                         diameter=diameter,
                         names=names,
                         mount=mount)
def create_configuration_from_MIDfile(antfile: str,
                                      location=None,
                                      mount: str = 'azel',
                                      rmax=None,
                                      name='') -> Configuration:
    """ Define from a file

    :param names: Antenna names
    :param antfile: Antenna file name
    :param mount: mount type: 'azel', 'xy'
    :return: Configuration
    """

    # X Y Z Diam Station
    # 9.36976 35.48262 1052.99987 13.50 M001
    antxyz = numpy.genfromtxt(antfile,
                              skip_header=5,
                              usecols=[0, 1, 2],
                              delimiter=" ")

    antxyz = xyz_at_latitude(antxyz, location.lat.rad)
    antxyz += [
        location.geocentric[0].to(u.m).value,
        location.geocentric[1].to(u.m).value,
        location.geocentric[2].to(u.m).value
    ]

    nants = antxyz.shape[0]
    assert antxyz.shape[
        1] == 3, "Antenna array has wrong shape %s" % antxyz.shape

    anames = numpy.genfromtxt(antfile,
                              dtype='str',
                              skip_header=5,
                              usecols=[4],
                              delimiter=" ")
    mounts = numpy.repeat(mount, nants)
    diameters = numpy.genfromtxt(antfile,
                                 dtype='str',
                                 skip_header=5,
                                 usecols=[3],
                                 delimiter=" ")

    antxyz, diameters, anames, mounts = limit_rmax(antxyz, diameters, anames,
                                                   mounts, rmax)

    fc = Configuration(location=location,
                       names=anames,
                       mount=mounts,
                       xyz=antxyz,
                       diameter=diameters,
                       name=name)

    return fc
def create_configuration_from_SKAfile(antfile: str,
                                      mount: str = 'azel',
                                      names: str = "%d",
                                      rmax=None,
                                      name='',
                                      location=None) -> Configuration:
    """ Define from a file

    :param names: Antenna names
    :param antfile: Antenna file name
    :param location:
    :param mount: mount type: 'azel', 'xy', 'equatorial'
    :param diameter: Effective diameter of station or antenna
    :return: Configuration
    """
    antdiamlonglat = numpy.genfromtxt(antfile,
                                      usecols=[0, 1, 2],
                                      delimiter="\t")

    assert antdiamlonglat.shape[1] == 3, ("Antenna array has wrong shape %s" %
                                          antdiamlonglat.shape)
    antxyz = numpy.zeros([antdiamlonglat.shape[0] - 1, 3])
    diameters = numpy.zeros([antdiamlonglat.shape[0] - 1])
    for ant in range(antdiamlonglat.shape[0] - 1):
        loc = EarthLocation(lon=antdiamlonglat[ant, 1],
                            lat=antdiamlonglat[ant, 2],
                            height=0.0).geocentric
        antxyz[ant] = [
            loc[0].to(u.m).value, loc[1].to(u.m).value, loc[2].to(u.m).value
        ]
        diameters[ant] = antdiamlonglat[ant, 0]

    nants = antxyz.shape[0]
    anames = [names % ant for ant in range(nants)]
    mounts = numpy.repeat(mount, nants)
    antxyz, diameters, anames, mounts = limit_rmax(antxyz, diameters, anames,
                                                   mounts, rmax)

    fc = Configuration(location=location,
                       names=anames,
                       mount=mounts,
                       xyz=antxyz,
                       diameter=diameters,
                       name=name)
    return fc
예제 #7
0
def create_configuration_from_SKAfile(antfile: str,
                                      mount: str = 'altaz',
                                      names: str = "%d",
                                      rmax=None, name='') -> Configuration:
    """ Define from a file

    :param names: Antenna names
    :param antfile: Antenna file name
    :param mount: mount type: 'altaz', 'xy'
    :return: Configuration
    """
    # Diameter, longitude, latitude
    # 15.00	21.44241720	-30.7342510
    # 35	116.7644482	-26.82472208
    antdiamlonglat = numpy.genfromtxt(antfile, skip_header=0, usecols=[0, 1, 2], delimiter="\t")
    assert antdiamlonglat.shape[1] == 3, ("Antenna array has wrong shape %s" % antdiamlonglat.shape)
    antxyz = numpy.zeros([antdiamlonglat.shape[0] - 1, 3])
    diameters = numpy.zeros([antdiamlonglat.shape[0] - 1])
    location = EarthLocation(lon=antdiamlonglat[-1, 1], lat=antdiamlonglat[-1, 2], height=0.0)
    for ant in range(antdiamlonglat.shape[0] - 1):
        loc = EarthLocation(lon=antdiamlonglat[ant, 1], lat=antdiamlonglat[ant, 2], height=0.0).geocentric
        antxyz[ant] = [loc[0].to(u.m).value, loc[1].to(u.m).value, loc[2].to(u.m).value]
        diameters[ant] = antdiamlonglat[ant, 0]
    
    if rmax is not None:
        lantxyz = antxyz - numpy.average(antxyz, axis=0)
        r = numpy.sqrt(lantxyz[:, 0] ** 2 + lantxyz[:, 1] ** 2 + lantxyz[:, 2] ** 2)
        antxyz = antxyz[r < rmax]
        log.debug('create_configuration_from_file: Maximum radius %.1f m includes %d antennas/stations' %
                  (rmax, antxyz.shape[0]))
        diameters = diameters[r < rmax]
    else:
        log.debug('create_configuration_from_file: %d antennas/stations' %
                  (antxyz.shape[0]))
    
    nants = antxyz.shape[0]
    anames = [names % ant for ant in range(nants)]
    mounts = numpy.repeat(mount, nants)
    fc = Configuration(location=location, names=anames, mount=mounts, xyz=antxyz, frame='global',
                       diameter=diameters, name=name)
    return fc
def create_configuration_from_file(antfile: str,
                                   location: EarthLocation = None,
                                   mount: str = 'azel',
                                   names: str = "%d",
                                   diameter=35.0,
                                   rmax=None,
                                   name='') -> Configuration:
    """ Define from a file

    :param names: Antenna names
    :param antfile: Antenna file name
    :param location:
    :param mount: mount type: 'azel', 'xy', 'equatorial'
    :param diameter: Effective diameter of station or antenna
    :return: Configuration
    """
    antxyz = numpy.genfromtxt(antfile, delimiter=",")
    assert antxyz.shape[1] == 3, ("Antenna array has wrong shape %s" %
                                  antxyz.shape)
    latitude = location.geodetic[1].to(u.rad).value
    antxyz = xyz_at_latitude(antxyz, latitude)
    antxyz += [
        location.geocentric[0].to(u.m).value,
        location.geocentric[1].to(u.m).value,
        location.geocentric[2].to(u.m).value
    ]

    nants = antxyz.shape[0]
    diameters = diameter * numpy.ones(nants)
    anames = [names % ant for ant in range(nants)]
    mounts = numpy.repeat(mount, nants)
    antxyz, diameters, anames, mounts = limit_rmax(antxyz, diameters, anames,
                                                   mounts, rmax)

    fc = Configuration(location=location,
                       names=anames,
                       mount=mounts,
                       xyz=antxyz,
                       diameter=diameters,
                       name=name)
    return fc
예제 #9
0
def create_configuration_from_MIDfile(antfile: str, location=None,
                                      mount: str = 'altaz',
                                      rmax=None, name='') -> Configuration:
    """ Define from a file

    :param names: Antenna names
    :param antfile: Antenna file name
    :param mount: mount type: 'altaz', 'xy'
    :return: Configuration
    """
    # X Y Z Diam Station
    # 5109237.714735 2006795.661955 -3239109.183708 13.5 M000
    antdiamlonglat = numpy.genfromtxt(antfile, skip_header=5, usecols=[0, 1, 2, 3, 4], delimiter=" ", dtype="f8, f8, "
                                                                                                            "f8, f8, S8")
    antxyz = numpy.zeros([len(antdiamlonglat), 3])
    diameters = numpy.zeros([len(antdiamlonglat)])
    names = list()
    for ant, line in enumerate(antdiamlonglat):
        lline=list(line)
        antxyz[ant, :] = lline[0:3]
        diameters[ant] = lline[3]
        names.append(lline[4])
    
    if rmax is not None:
        lantxyz = antxyz - numpy.average(antxyz, axis=0)
        r = numpy.sqrt(lantxyz[:, 0] ** 2 + lantxyz[:, 1] ** 2 + lantxyz[:, 2] ** 2)
        antxyz = antxyz[r < rmax]
        log.debug('create_configuration_from_file: Maximum radius %.1f m includes %d antennas/stations' %
                  (rmax, antxyz.shape[0]))
        diameters = diameters[r < rmax]
        names = numpy.array(names)[r < rmax]
    else:
        log.debug('create_configuration_from_file: %d antennas/stations' %
                  (antxyz.shape[0]))
    
    nants = antxyz.shape[0]
    mounts = numpy.repeat(mount, nants)
    fc = Configuration(location=location, names=names, mount=mounts, xyz=antxyz, frame='global',
                       diameter=diameters, name=name)
    return fc
def import_visibility_from_oskar(oskar_file: str) -> Visibility:
    """ Import a visibility set from an OSKAR visibility file

    :param oskar_file: Name of OSKAR visibility file
    :returns: Visibility
    """
    
    # Extract data from Oskar file
    oskar_vis = OskarVis(oskar_file)
    ra, dec = oskar_vis.phase_centre()
    a1, a2 = oskar_vis.stations(flatten=True)
    
    # Make configuration
    location = EarthLocation(lon=oskar_vis.telescope_lon,
                             lat=oskar_vis.telescope_lat,
                             height=oskar_vis.telescope_alt)
    antxyz = numpy.transpose([oskar_vis.station_x,
                              oskar_vis.station_y,
                              oskar_vis.station_z])
    config = Configuration(
        name=oskar_vis.telescope_path,
        location=location,
        xyz=antxyz
    )
    
    # Construct visibilities
    return Visibility(
        frequency=[oskar_vis.frequency(i) for i in range(oskar_vis.num_channels)],
        phasecentre=SkyCoord(frame=ICRS, ra=ra, dec=dec, unit=u.deg),
        configuration=config,
        uvw=numpy.transpose(oskar_vis.uvw(flatten=True)),
        time=oskar_vis.times(flatten=True),
        antenna1=a1,
        antenna2=a2,
        vis=oskar_vis.amplitudes(flatten=True),
        weight=numpy.ones(a1.shape))
예제 #11
0
def create_visibility_from_ms(msname, channum=0, ack=False):
    """ Minimal MS to Visibility converter

    The MS format is much more general than the ARL Visibility so we cut many corners. This requires casacore to be
    installed. If not an exception ModuleNotFoundError is raised.

    Creates a list of Visibilities, one per phasecentre
    """
    try:
        from casacore.tables import table  # pylint: disable=import-error
    except ModuleNotFoundError:
        raise ModuleNotFoundError("casacore is not installed")

    tab = table(msname, ack=ack)
    log.debug("create_visibility_from_ms: %s" % str(tab.info()))
    fields = numpy.unique(tab.getcol('FIELD_ID'))
    log.debug("create_visibility_from_ms: Found unique field ids %s" %
              str(fields))
    vis_list = list()
    for field in fields:
        # First get the main table information
        ms = tab.query("FIELD_ID==%d" % field)
        log.debug("create_visibility_from_ms: Found %d rows for field %d" %
                  (ms.nrows(), field))
        time = ms.getcol('TIME')
        channels = len(numpy.transpose(ms.getcol('DATA'))[0])
        log.debug("create_visibility_from_ms: Found %d channels" % (channels))
        try:
            vis = ms.getcol('DATA')[:, channum, :]
        except IndexError:
            raise IndexError("channel number exceeds max. within ms")
        weight = ms.getcol('WEIGHT')
        uvw = -1 * ms.getcol('UVW')
        antenna1 = ms.getcol('ANTENNA1')
        antenna2 = ms.getcol('ANTENNA2')
        integration_time = ms.getcol('INTERVAL')
        ddid = ms.getcol('DATA_DESC_ID')

        # Now get info from the subtables
        spwtab = table('%s/SPECTRAL_WINDOW' % msname, ack=False)
        cfrequency = spwtab.getcol('CHAN_FREQ')
        frequency = numpy.array([cfrequency[dd] for dd in ddid])[:, channum]
        cchannel_bandwidth = spwtab.getcol('CHAN_WIDTH')
        channel_bandwidth = numpy.array(
            [cchannel_bandwidth[dd] for dd in ddid])[:, 0]

        uvw *= frequency[:, numpy.newaxis] / constants.c.to('m s^-1').value

        # Get polarisation info
        poltab = table('%s/POLARIZATION' % msname, ack=False)
        corr_type = poltab.getcol('CORR_TYPE')
        # These correspond to the CASA Stokes enumerations
        if numpy.array_equal(corr_type[0], [1, 2, 3, 4]):
            polarisation_frame = PolarisationFrame('stokesIQUV')
        elif numpy.array_equal(corr_type[0], [5, 6, 7, 8]):
            polarisation_frame = PolarisationFrame('circular')
        elif numpy.array_equal(corr_type[0], [9, 10, 11, 12]):
            polarisation_frame = PolarisationFrame('linear')
        else:
            raise KeyError("Polarisation not understood: %s" % str(corr_type))

        print("create_visibility_from_ms: polarisation %s" %
              polarisation_frame.type)

        # Get configuration
        anttab = table('%s/ANTENNA' % msname, ack=False)
        mount = anttab.getcol('MOUNT')
        names = anttab.getcol('NAME')
        diameter = anttab.getcol('DISH_DIAMETER')
        xyz = anttab.getcol('POSITION')
        configuration = Configuration(name='',
                                      data=None,
                                      location=None,
                                      names=names,
                                      xyz=xyz,
                                      mount=mount,
                                      frame=None,
                                      receptor_frame=ReceptorFrame("linear"),
                                      diameter=diameter)

        # Get phasecentres
        fieldtab = table('%s/FIELD' % msname, ack=False)
        pc = fieldtab.getcol('PHASE_DIR')[field, 0, :]
        phasecentre = SkyCoord(ra=[pc[0]] * u.rad,
                               dec=pc[1] * u.rad,
                               frame='icrs',
                               equinox='J2000')

        vis_list.append(
            Visibility(uvw=uvw,
                       time=time,
                       antenna1=antenna1,
                       antenna2=antenna2,
                       frequency=frequency,
                       vis=vis,
                       weight=weight,
                       imaging_weight=weight,
                       integration_time=integration_time,
                       channel_bandwidth=channel_bandwidth,
                       configuration=configuration,
                       phasecentre=phasecentre,
                       polarisation_frame=polarisation_frame))
    return vis_list
예제 #12
0
def create_blockvisibility_from_ms(msname, channum=None, ack=False):
    """ Minimal MS to BlockVisibility converter

    The MS format is much more general than the ARL BlockVisibility so we cut many corners. This requires casacore to be
    installed. If not an exception ModuleNotFoundError is raised.

    Creates a list of BlockVisibility's, split by field and spectral window
    
    :param msname: File name of MS
    :param channum: range of channels e.g. range(17,32), default is None meaning all
    :return:
    """
    try:
        from casacore.tables import table  # pylint: disable=import-error
    except ModuleNotFoundError:
        raise ModuleNotFoundError("casacore is not installed")

    tab = table(msname, ack=ack)
    log.debug("create_blockvisibility_from_ms: %s" % str(tab.info()))

    fields = numpy.unique(tab.getcol('FIELD_ID'))
    dds = numpy.unique(tab.getcol('DATA_DESC_ID'))
    log.debug(
        "create_blockvisibility_from_ms: Found unique fields %s, unique data descriptions %s"
        % (str(fields), str(dds)))
    vis_list = list()
    for dd in dds:
        dtab = table(msname, ack=ack).query('DATA_DESC_ID==%d' % dd, style='')
        for field in fields:
            ms = dtab.query('FIELD_ID==%d' % field, style='')
            assert ms.nrows(
            ) > 0, "Empty selection for FIELD_ID=%d and DATA_DESC_ID=%d" % (
                field, dd)
            log.debug("create_blockvisibility_from_ms: Found %d rows" %
                      (ms.nrows()))
            time = ms.getcol('TIME')
            channels = ms.getcol('DATA').shape[-2]
            log.debug("create_visibility_from_ms: Found %d channels" %
                      (channels))
            if channum is None:
                channum = range(channels)
            try:
                ms_vis = ms.getcol('DATA')[:, channum, :]
                ms_weight = ms.getcol('WEIGHT')[:, :]
            except IndexError:
                raise IndexError("channel number exceeds max. within ms")
            uvw = -1 * ms.getcol('UVW')
            antenna1 = ms.getcol('ANTENNA1')
            antenna2 = ms.getcol('ANTENNA2')
            integration_time = ms.getcol('INTERVAL')

            # Now get info from the subtables
            spwtab = table('%s/SPECTRAL_WINDOW' % msname, ack=False)
            cfrequency = spwtab.getcol('CHAN_FREQ')[dd][channum]
            cchannel_bandwidth = spwtab.getcol('CHAN_WIDTH')[dd][channum]
            nchan = cfrequency.shape[0]

            # Get polarisation info
            poltab = table('%s/POLARIZATION' % msname, ack=False)
            corr_type = poltab.getcol('CORR_TYPE')
            # These correspond to the CASA Stokes enumerations
            if numpy.array_equal(corr_type[0], [1, 2, 3, 4]):
                polarisation_frame = PolarisationFrame('stokesIQUV')
            elif numpy.array_equal(corr_type[0], [5, 6, 7, 8]):
                polarisation_frame = PolarisationFrame('circular')
            elif numpy.array_equal(corr_type[0], [9, 10, 11, 12]):
                polarisation_frame = PolarisationFrame('linear')
            else:
                raise KeyError("Polarisation not understood: %s" %
                               str(corr_type))

            npol = 4

            # Get configuration
            anttab = table('%s/ANTENNA' % msname, ack=False)
            nants = anttab.nrows()
            mount = anttab.getcol('MOUNT')
            names = anttab.getcol('NAME')
            diameter = anttab.getcol('DISH_DIAMETER')
            xyz = anttab.getcol('POSITION')
            configuration = Configuration(
                name='',
                data=None,
                location=None,
                names=names,
                xyz=xyz,
                mount=mount,
                frame=None,
                receptor_frame=ReceptorFrame("linear"),
                diameter=diameter)

            # Get phasecentres
            fieldtab = table('%s/FIELD' % msname, ack=False)
            pc = fieldtab.getcol('PHASE_DIR')[field, 0, :]
            phasecentre = SkyCoord(ra=[pc[0]] * u.rad,
                                   dec=pc[1] * u.rad,
                                   frame='icrs',
                                   equinox='J2000')

            bv_times = numpy.unique(time)
            ntimes = len(bv_times)

            bv_vis = numpy.zeros([ntimes, nants, nants, nchan,
                                  npol]).astype('complex')
            bv_weight = numpy.zeros([ntimes, nants, nants, nchan, npol])
            bv_uvw = numpy.zeros([ntimes, nants, nants, 3])

            time_last = time[0]
            time_index = 0
            for row, _ in enumerate(ms_vis):
                # MS has shape [row, npol, nchan]
                # BV has shape [ntimes, nants, nants, nchan, npol]
                if time[row] != time_last:
                    assert time[
                        row] > time_last, "MS is not time-sorted - cannot convert"
                    time_index += 1
                    time_last = time[row]
                bv_vis[time_index, antenna2[row], antenna1[row],
                       ...] = ms_vis[row, ...]
                bv_weight[time_index, antenna2[row], antenna1[row], :,
                          ...] = ms_weight[row, numpy.newaxis, ...]
                bv_uvw[time_index, antenna2[row],
                       antenna1[row], :] = uvw[row, :]

            vis_list.append(
                BlockVisibility(uvw=bv_uvw,
                                time=bv_times,
                                frequency=cfrequency,
                                channel_bandwidth=cchannel_bandwidth,
                                vis=bv_vis,
                                weight=bv_weight,
                                configuration=configuration,
                                phasecentre=phasecentre,
                                polarisation_frame=polarisation_frame))
        tab.close()
    return vis_list
    def __initData_WGS84(self):
        """Private function to generate a random set of data for writing a Measurements
        file.  The data is returned as a dictionary with keys:
         * freq - frequency array in Hz
         * site - observatory object
         * stands - array of stand numbers
         * bl - list of baseline pairs in real stand numbers
         * vis - array of visibility data in baseline x freq format
        """
        if run_ms_tests == False:
            return

        # Frequency range
        freq = numpy.arange(0, 512) * 20e6 / 512 + 40e6
        channel_width = numpy.full_like(freq, 20e6 / 512.)

        # Site and stands
        obs = EarthLocation(lon="+116.6356824",
                            lat="-26.70130064",
                            height=377.0)

        names = numpy.array(['A%02d' % i for i in range(36)])
        mount = numpy.array(['equat' for i in range(36)])
        diameter = numpy.array([12 for i in range(36)])
        xyz = numpy.array([[-175.233429, +1673.460938, 0.0000],
                           [+261.119019, +796.922119, 0.0000],
                           [-29.2005200, +744.432068, 0.0000],
                           [-289.355286, +586.936035, 0.0000],
                           [-157.031570, +815.570068, 0.0000],
                           [-521.311646, +754.674927, 0.0000],
                           [-1061.114258, +840.541443, 0.0000],
                           [-921.829407, +997.627686, 0.0000],
                           [-818.293579, +1142.272095, 0.0000],
                           [-531.752808, +850.726257, 0.0000],
                           [+81.352448, +790.245117, 0.0000],
                           [+131.126358, +1208.831909, 0.0000],
                           [-1164.709351, +316.779236, 0.0000],
                           [-686.248901, +590.285278, 0.0000],
                           [-498.987305, +506.338226, 0.0000],
                           [-182.249146, +365.113464, 0.0000],
                           [+420.841858, +811.081543, 0.0000],
                           [+804.107910, +1273.328369, 0.0000],
                           [-462.810394, +236.353790, 0.0000],
                           [-449.772339, +15.039755, 0.0000],
                           [+13.791821, +110.971809, 0.0000],
                           [-425.687317, -181.908752, 0.0000],
                           [-333.404053, -503.603394, 0.0000],
                           [-1495.472412, +1416.063232, 0.0000],
                           [-1038.578857, +1128.367920, 0.0000],
                           [-207.151749, +956.312561, 0.0000],
                           [-389.051880, +482.405670, 0.0000],
                           [-434.000000, +510.000000, 0.0000],
                           [-398.000000, +462.000000, 0.0000],
                           [-425.000000, +475.000000, 0.0000],
                           [-400.000000, +3664.000000, 0.0000],
                           [+1796.000000, +1468.000000, 0.0000],
                           [+2600.000000, -1532.000000, 0.0000],
                           [-400.000000, -2336.000000, 0.0000],
                           [-3400.00000, -1532.000000, 0.0000],
                           [-2596.000000, +1468.000000, 0.0000]])

        site_config = Configuration(name='ASKAP',
                                    data=None,
                                    location=obs,
                                    names=names,
                                    xyz=xyz,
                                    mount=mount,
                                    frame=None,
                                    receptor_frame=ReceptorFrame("linear"),
                                    diameter=diameter)
        antennas = []
        for i in range(len(names)):
            antennas.append(
                Antenna(i, Stand(names[i], xyz[i, 0], xyz[i, 1], xyz[i, 2])))

        # Set baselines and data
        blList = []
        N = len(antennas)

        antennas2 = antennas

        for i in range(0, N - 1):
            for j in range(i + 1, N):
                blList.append((antennas[i], antennas2[j]))

        visData = numpy.random.rand(len(blList), len(freq))
        visData = visData.astype(numpy.complex64)

        return {
            'freq': freq,
            'channel_width': channel_width,
            'site': site_config,
            'antennas': antennas,
            'bl': blList,
            'vis': visData
        }
    def __initData(self):
        """Private function to generate a random set of data for writing a UVFITS
        file.  The data is returned as a dictionary with keys:
         * freq - frequency array in Hz
         * site - Observatory object
         * stands - array of stand numbers
         * bl - list of baseline pairs in real stand numbers
         * vis - array of visibility data in baseline x freq format
        """
        if run_ms_tests == False:
            return

        # Frequency range
        freq = numpy.arange(0, 512) * 20e6 / 512 + 40e6
        channel_width = numpy.full_like(freq, 20e6 / 512.)

        # Site and stands
        obs = EarthLocation(lon="116.76444824",
                            lat="-26.824722084",
                            height=300.0)

        mount = numpy.array([
            'equat', 'equat', 'equat', 'equat', 'equat', 'equat', 'equat',
            'equat', 'equat', 'equat'
        ])
        names = numpy.array([
            'ak02', 'ak04', 'ak05', 'ak12', 'ak13', 'ak14', 'ak16', 'ak24',
            'ak28', 'ak30'
        ])
        diameter = numpy.array(
            [12., 12., 12., 12., 12., 12., 12., 12., 12., 12.])
        xyz = numpy.array(
            [[-2556109.98244348, 5097388.70050131, -2848440.1332423],
             [-2556087.396082, 5097423.589662, -2848396.867933],
             [-2556028.60254059, 5097451.46195695, -2848399.83113161],
             [-2556496.23893101, 5097333.71466669, -2848187.33832738],
             [-2556407.35299627, 5097064.98390756, -2848756.02069474],
             [-2555972.78456557, 5097233.65481756, -2848839.88915184],
             [-2555592.88867802, 5097835.02121109, -2848098.26409648],
             [-2555959.34313275, 5096979.52802882, -2849303.57702486],
             [-2556552.97431815, 5097767.23612874, -2847354.29540396],
             [-2557348.40370367, 5097170.17682775, -2847716.21368966]])

        site_config = Configuration(name='ASKAP',
                                    data=None,
                                    location=obs,
                                    names=names,
                                    xyz=xyz,
                                    mount=mount,
                                    frame=None,
                                    receptor_frame=ReceptorFrame("linear"),
                                    diameter=diameter)
        antennas = []
        for i in range(len(names)):
            antennas.append(
                Antenna(i, Stand(names[i], xyz[i, 0], xyz[i, 1], xyz[i, 2])))

        # Set baselines and data
        blList = []
        N = len(antennas)

        antennas2 = antennas

        for i in range(0, N - 1):
            for j in range(i + 1, N):
                blList.append((antennas[i], antennas2[j]))

        visData = numpy.random.rand(len(blList), len(freq))
        visData = visData.astype(numpy.complex64)

        return {
            'freq': freq,
            'channel_width': channel_width,
            'site': site_config,
            'antennas': antennas,
            'bl': blList,
            'vis': visData
        }
예제 #15
0
def create_blockvisibility_from_ms(msname, channum=None, start_chan=None, end_chan=None, ack=False,
                                   datacolumn='DATA', selected_sources=None, selected_dds=None):
    """ Minimal MS to BlockVisibility converter

    The MS format is much more general than the ARL BlockVisibility so we cut many corners. This requires casacore to be
    installed. If not an exception ModuleNotFoundError is raised.

    Creates a list of BlockVisibility's, split by field and spectral window
    
    Reading of a subset of channels is possible using either start_chan and end_chan or channnum. Using start_chan 
    and end_chan is preferred since it only reads the channels required. Channum is more flexible and can be used to
    read a random list of channels.
    
    :param msname: File name of MS
    :param channum: range of channels e.g. range(17,32), default is None meaning all
    :param start_chan: Starting channel to read
    :param end_chan: End channel to read
    :return:
    """
    try:
        from casacore.tables import table  # pylint: disable=import-error
    except ModuleNotFoundError:
        raise ModuleNotFoundError("casacore is not installed")
    try:
        from processing_components.visibility import msv2
    except ModuleNotFoundError:
        raise ModuleNotFoundError("cannot import msv2")

    tab = table(msname, ack=ack)
    log.debug("create_blockvisibility_from_ms: %s" % str(tab.info()))

    if selected_sources is None:
        fields = numpy.unique(tab.getcol('FIELD_ID'))
    else:
        fieldtab = table('%s/FIELD' % msname, ack=False)
        sources = fieldtab.getcol('NAME')
        fields = list()
        for field, source in enumerate(sources):
            if source in selected_sources: fields.append(field)
        assert len(fields) > 0, "No sources selected"
        
    if selected_dds is None:
        dds = numpy.unique(tab.getcol('DATA_DESC_ID'))
    else:
        dds = selected_dds
        
    log.debug("create_blockvisibility_from_ms: Reading unique fields %s, unique data descriptions %s" % (
        str(fields), str(dds)))
    vis_list = list()
    for field in fields:
        ftab = table(msname, ack=ack).query('FIELD_ID==%d' % field, style='')
        for dd in dds:
            meta = {'MSV2':{'FIELD_ID': field, 'DATA_DESC_ID':dd}}
            ms = ftab.query('DATA_DESC_ID==%d' % dd, style='')
            assert ms.nrows() > 0, "Empty selection for FIELD_ID=%d and DATA_DESC_ID=%d" % (field, dd)
            log.debug("create_blockvisibility_from_ms: Found %d rows" % (ms.nrows()))
            # The TIME column has descriptor:
            # {'valueType': 'double', 'dataManagerType': 'IncrementalStMan', 'dataManagerGroup': 'TIME',
            # 'option': 0, 'maxlen': 0, 'comment': 'Modified Julian Day',
            # 'keywords': {'QuantumUnits': ['s'], 'MEASINFO': {'type': 'epoch', 'Ref': 'UTC'}}}
            otime = ms.getcol('TIME')
            datacol = ms.getcol(datacolumn, nrow=1)
            datacol_shape = list(datacol.shape)
            channels = datacol.shape[-2]
            log.debug("create_blockvisibility_from_ms: Found %d channels" % (channels))
            if channum is None:
                if start_chan is not None and end_chan is not None:
                    try:
                        log.debug("create_blockvisibility_from_ms: Reading channels from %d to %d" %
                                  (start_chan, end_chan))
                        print("create_blockvisibility_from_ms: Reading channels from %d to %d (inclusive)" %
                              (start_chan, end_chan))
                        blc = [start_chan, 0]
                        trc = [end_chan, datacol_shape[-1] - 1]
                        channum = range(start_chan, end_chan+1)
                        ms_vis = ms.getcolslice(datacolumn, blc=blc, trc=trc)
                        ms_weight = ms.getcol('WEIGHT')
                    except IndexError:
                        raise IndexError("channel number exceeds max. within ms")

                else:
                    log.debug("create_blockvisibility_from_ms: Reading all %d channels" % (channels))
                    try:
                        channum = range(channels)
                        ms_vis = ms.getcol(datacolumn)[:, channum, :]
                        ms_weight = ms.getcol('WEIGHT')
                        channum = range(channels)
                    except IndexError:
                        raise IndexError("channel number exceeds max. within ms")
            else:
                log.debug("create_blockvisibility_from_ms: Reading channels %s " % (channum))
                channum = range(channels)
                try:
                    ms_vis = ms.getcol(datacolumn)[:, channum, :]
                    ms_weight = ms.getcol('WEIGHT')[:, :]
                except IndexError:
                    raise IndexError("channel number exceeds max. within ms")

            uvw = -1 * ms.getcol('UVW')
            antenna1 = ms.getcol('ANTENNA1')
            antenna2 = ms.getcol('ANTENNA2')
            integration_time = ms.getcol('INTERVAL')

#            time = Time((time-integration_time/2.0)/86400+ 2400000.5,format='jd',scale='utc').utc.value
            time = (otime - integration_time / 2.0)

            start_time = numpy.min(time)/86400.0
            end_time = numpy.max(time)/86400.0
            
            log.debug("create_blockvisibility_from_ms: Observation from %s to %s" %
                      (Time(start_time, format='mjd').iso, Time(end_time, format='mjd').iso))

            # Now get info from the subtables
            spwtab = table('%s/SPECTRAL_WINDOW' % msname, ack=False)
            cfrequency = spwtab.getcol('CHAN_FREQ')[dd][channum]
            cchannel_bandwidth = spwtab.getcol('CHAN_WIDTH')[dd][channum]
            nchan = cfrequency.shape[0]
            
            # Get polarisation info
            npol = 4
            poltab = table('%s/POLARIZATION' % msname, ack=False)
            corr_type = poltab.getcol('CORR_TYPE')
            # These correspond to the CASA Stokes enumerations
            if numpy.array_equal(corr_type[0], [1, 2, 3, 4]):
                polarisation_frame = PolarisationFrame('stokesIQUV')
            elif numpy.array_equal(corr_type[0], [5, 6, 7, 8]):
                polarisation_frame = PolarisationFrame('circular')
            elif numpy.array_equal(corr_type[0], [9, 10, 11, 12]):
                polarisation_frame = PolarisationFrame('linear')
            elif numpy.array_equal(corr_type[0], [9]):
                npol = 1
                polarisation_frame = PolarisationFrame('stokesI')
            else:
                raise KeyError("Polarisation not understood: %s" % str(corr_type))
            
            
            # Get configuration
            anttab = table('%s/ANTENNA' % msname, ack=False)
            nants = anttab.nrows()
            mount = anttab.getcol('MOUNT')
            names = anttab.getcol('NAME')
            diameter = anttab.getcol('DISH_DIAMETER')
            xyz = anttab.getcol('POSITION')
            configuration = Configuration(name='', data=None, location=None,
                                          names=names, xyz=xyz, mount=mount, frame=None,
                                          receptor_frame=ReceptorFrame("linear"),
                                          diameter=diameter)
            # Get phasecentres
            fieldtab = table('%s/FIELD' % msname, ack=False)
            pc = fieldtab.getcol('PHASE_DIR')[field, 0, :]
            source = fieldtab.getcol('NAME')[field]
            phasecentre = SkyCoord(ra=pc[0] * u.rad, dec=pc[1] * u.rad, frame='icrs', equinox='J2000')

            time_index_row = numpy.zeros_like(time, dtype='int')
            time_last = time[0]
            time_index = 0
            for row, _ in enumerate(time):
                if time[row] > time_last + integration_time[row]:
                    assert time[row] > time_last, "MS is not time-sorted - cannot convert"
                    time_index += 1
                    time_last = time[row]
                time_index_row[row] = time_index

            ntimes = time_index + 1
            
            bv_times = numpy.zeros([ntimes])
            bv_vis = numpy.zeros([ntimes, nants, nants, nchan, npol]).astype('complex')
            bv_weight = numpy.zeros([ntimes, nants, nants, nchan, npol])
            bv_imaging_weight = numpy.zeros([ntimes, nants, nants, nchan, npol])
            bv_uvw = numpy.zeros([ntimes, nants, nants, 3])
            bv_integration_time = numpy.zeros([ntimes])

            for row, _ in enumerate(time):
                time_index = time_index_row[row]
                bv_times[time_index] = time[row]
                bv_vis[time_index, antenna2[row], antenna1[row], ...] = ms_vis[row, ...]
                bv_weight[time_index, antenna2[row], antenna1[row], :, ...] = ms_weight[row, numpy.newaxis, ...]
                bv_imaging_weight[time_index, antenna2[row], antenna1[row], :, ...] = ms_weight[row, numpy.newaxis, ...]
                bv_uvw[time_index, antenna2[row], antenna1[row], :] = uvw[row, :]
                bv_integration_time[time_index] = integration_time[row]

            vis_list.append(BlockVisibility(uvw=bv_uvw,
                                            time=bv_times,
                                            frequency=cfrequency,
                                            channel_bandwidth=cchannel_bandwidth,
                                            vis=bv_vis,
                                            weight=bv_weight,
                                            integration_time = bv_integration_time,
                                            imaging_weight=bv_imaging_weight,
                                            configuration=configuration,
                                            phasecentre=phasecentre,
                                            polarisation_frame=polarisation_frame,
                                            source=source, meta=meta))
        tab.close()
    return vis_list
예제 #16
0
def create_blockvisibility_from_uvfits(fitsname, channum=None, ack=False, antnum=None):
    """ Minimal UVFIT to BlockVisibility converter

    The UVFITS format is much more general than the ARL BlockVisibility so we cut many corners. 
    
    Creates a list of BlockVisibility's, split by field and spectral window
    
    :param fitsname: File name of UVFITS
    :param channum: range of channels e.g. range(17,32), default is None meaning all
    :param antnum: the number of antenna
    :return:
    """
    def ParamDict(hdul):
        "Return the dictionary of the random parameters"

        """
        The keys of the dictionary are the parameter names uppercased for
        consistency. The values are the column numbers.

        If multiple parameters have the same name (e.g., DATE) their
        columns are entered as a list.
        """

        pre=re.compile(r"PTYPE(?P<i>\d+)")
        res={}
        for k,v in hdul.header.items():
            m=pre.match(k)
            if m :
                vu=v.upper()
                if vu in res:
                    res[ vu ] = [ res[vu], int(m.group("i")) ]
                else:
                    res[ vu ] = int(m.group("i"))
        return res


    # Open the file
    with fits.open(fitsname) as hdul:

        # Read Spectral Window
        nspw = hdul[0].header['NAXIS5']
        # Read Channel and Frequency Interval
        freq_ref = hdul[0].header['CRVAL4']
        mid_chan_freq = hdul[0].header['CRPIX4']
        delt_freq = hdul[0].header['CDELT4']
        # Real the number of channels in one spectral window
        channels = hdul[0].header['NAXIS4']
        freq = numpy.zeros([nspw, channels])
        # Read Frequency or IF
        freqhdulname="AIPS FQ"
        sdhu  = hdul.index_of(freqhdulname)
        if_freq = hdul[sdhu].data['IF FREQ'].ravel()
        for i in range(nspw):
            temp = numpy.array([if_freq[i] + freq_ref+delt_freq* ff for ff in range(channels)])
            freq[i,:] = temp[:]
        freq_delt = numpy.ones(channels) * delt_freq
        if channum is None:
            channum = range(channels)

        primary = hdul[0].data
        # Read time
        bvtimes = Time(hdul[0].data['DATE'], hdul[0].data['_DATE'], format='jd')
        bv_times  = numpy.unique(bvtimes.jd)
        ntimes   = len(bv_times)

                # # Get Antenna
        # blin = hdul[0].data['BASELINE']
        antennahdulname="AIPS AN"
        adhu  = hdul.index_of(antennahdulname)
        try:
            antenna_name = hdul[adhu].data['ANNAME']
            antenna_name = antenna_name.encode('ascii','ignore')
        except:
            antenna_name = None

        antenna_xyz = hdul[adhu].data['STABXYZ']
        antenna_mount =  hdul[adhu].data['MNTSTA']
        try:
            antenna_diameter = hdul[adhu].data['DIAMETER']
        except:
            antenna_diameter = None
        # To reading some UVFITS with wrong numbers of antenna
        if antnum is not None:
            if antenna_name is not None:
                antenna_name = antenna_name[:antnum]
                antenna_xyz = antenna_xyz[:antnum]
                antenna_mount = antenna_mount[:antnum]
                if antenna_diameter is not None:
                    antenna_diameter = antenna_diameter[:antnum]
        nants = len(antenna_xyz)

        # res= {}
        # for i,row in enumerate(fin[ahdul].data):
        #     res[row.field("ANNAME") ]  = i +1

        # Get polarisation info
        npol = hdul[0].header['NAXIS3']
        corr_type = numpy.arange(hdul[0].header['NAXIS3']) - (hdul[0].header['CRPIX3'] - 1)
        corr_type *= hdul[0].header['CDELT3']
        corr_type += hdul[0].header['CRVAL3']
        # xx yy xy yx
        # These correspond to the CASA Stokes enumerations
        if numpy.array_equal(corr_type, [1, 2, 3, 4]):
            polarisation_frame = PolarisationFrame('stokesIQUV')
        elif numpy.array_equal(corr_type, [-1, -2, -3, -4]):
            polarisation_frame = PolarisationFrame('circular')
        elif numpy.array_equal(corr_type, [-5, -6, -7, -8]):
            polarisation_frame = PolarisationFrame('linear')
        else:
            raise KeyError("Polarisation not understood: %s" % str(corr_type))            

        configuration = Configuration(name='', data=None, location=None,
                                        names=antenna_name, xyz=antenna_xyz, mount=antenna_mount, frame=None,
                                        receptor_frame=polarisation_frame,
                                        diameter=antenna_diameter)       

        # Get RA and DEC
        phase_center_ra_degrees = numpy.float(hdul[0].header['CRVAL6'])
        phase_center_dec_degrees = numpy.float(hdul[0].header['CRVAL7'])

        # Get phasecentres
        phasecentre = SkyCoord(ra=phase_center_ra_degrees * u.deg, dec=phase_center_dec_degrees * u.deg, frame='icrs', equinox='J2000')
                    
        # Get UVW
        d=ParamDict(hdul[0])
        if "UU" in d:
            uu = hdul[0].data['UU'] 
            vv = hdul[0].data['VV'] 
            ww = hdul[0].data['WW'] 
        else:
            uu = hdul[0].data['UU---SIN'] 
            vv = hdul[0].data['VV---SIN']
            ww = hdul[0].data['WW---SIN'] 
        _vis = hdul[0].data['DATA']

        #_vis.shape = (nchan, ntimes, (nants*(nants-1)//2 ), npol, -1)
        #self.vis = -(_vis[...,0] * 1.j + _vis[...,1])
        row = 0
        nchan = len(channum)
        vis_list = list()
        for spw_index in range(nspw):
            bv_vis = numpy.zeros([ntimes, nants, nants, nchan, npol]).astype('complex')
            bv_weight = numpy.zeros([ntimes, nants, nants, nchan, npol])
            bv_uvw = numpy.zeros([ntimes, nants, nants, 3])     
            for time_index , time in enumerate(bv_times):
                #restfreq = freq[channel_index] 
                for antenna1 in range(nants-1):
                    for antenna2 in range(antenna1 + 1, nants):
                        for channel_no, channel_index in enumerate(channum):
                            for pol_index in range(npol):
                                bv_vis[time_index, antenna2, antenna1, channel_no,pol_index] = complex(_vis[row,:,:,spw_index,channel_index, pol_index ,0],_vis[row,:,:,spw_index,channel_index,pol_index ,1])
                                bv_weight[time_index, antenna2, antenna1, channel_no, pol_index] = _vis[row,:,:,spw_index,channel_index,pol_index ,2]
                        bv_uvw[time_index, antenna2, antenna1, 0] = uu[row]* constants.c.value
                        bv_uvw[time_index, antenna2, antenna1, 1] = vv[row]* constants.c.value
                        bv_uvw[time_index, antenna2, antenna1, 2] = ww[row]* constants.c.value
                        row += 1 
            vis_list.append(BlockVisibility(uvw=bv_uvw,
                                            time=bv_times,
                                            frequency=freq[spw_index][channum],
                                            channel_bandwidth=freq_delt[channum],
                                            vis=bv_vis,
                                            weight=bv_weight,
                                            imaging_weight= bv_weight,
                                            configuration=configuration,
                                            phasecentre=phasecentre,
                                            polarisation_frame=polarisation_frame))
    return vis_list
예제 #17
0
def create_visibility_from_ms_maps(msname, poldef):
    """ Minimal MS to Visibility converter
        
        The MS format is much more general than the ARL Visibility so we cut many corners. This requires casacore to be
        installed. If not an exception ModuleNotFoundError is raised.
        
        Creates a list of Visibilities, one per phasecentre
    """
    
    try:
        from casacore.tables import table  # pylint: disable=import-error
    except ModuleNotFoundError:
        raise ModuleNotFoundError("casacore is not installed")
    
    tab = table(msname)
    print(tab.info())
    fields = numpy.unique(tab.getcol('FIELD_ID'))
    print("Found unique field ids %s" % fields)

    # for field in fields:
    # First get the main table information
    ms = tab.query("FIELD_ID==%d" % fields[0])
    print("Found %d rows for field %d" % (ms.nrows(), fields[0]))
    time = ms.getcol('TIME')
    weight = ms.getcol('WEIGHT')
    uvw = -1 * ms.getcol('UVW')
    antenna1 = ms.getcol('ANTENNA1')
    antenna2 = ms.getcol('ANTENNA2')
    integration_time = ms.getcol('INTERVAL')
    ddid = ms.getcol('DATA_DESC_ID')

    # Get polarisation info
    # poltab = table('%s/POLARIZATION' % msname, ack=False)
    # corr_type = poltab.getcol('CORR_TYPE')
    # TODO: Do interpretation correctly
    # polarisation_frame = PolarisationFrame('stokesIQUV')
    # Set the polarisation frame:
    if poldef == 'lin':
        polarisation_frame = PolarisationFrame('linear')
    if poldef == 'circ':
        polarisation_frame = PolarisationFrame('circular')

    # Get configuration
    anttab = table('%s/ANTENNA' % msname, ack=False)
    mount = anttab.getcol('MOUNT')
    names = anttab.getcol('NAME')
    diameter = anttab.getcol('DISH_DIAMETER')
    xyz = anttab.getcol('POSITION')
    configuration = Configuration(name='', data=None, location=None, names=names, xyz=xyz, mount=mount, frame=None, receptor_frame=ReceptorFrame("linear"), diameter=diameter)
    # Get phasecentres
    fieldtab = table('%s/FIELD' % msname, ack=False)
    pc = fieldtab.getcol('PHASE_DIR')[fields[0], 0, :]
    print(pc[0], pc[1])
    phasecentre = SkyCoord(ra=[pc[0]] * u.rad, dec=pc[1] * u.rad, frame='icrs', equinox='J2000')
    
    channels = len(numpy.transpose(ms.getcol('DATA'))[0])
    print("Found %d channels" % (channels))
    
    spwtab = table('%s/SPECTRAL_WINDOW' % msname, ack=False)
    cfrequency = spwtab.getcol('CHAN_FREQ')
    
    cchannel_bandwidth = spwtab.getcol('CHAN_WIDTH')
    channel_bandwidth = numpy.array([cchannel_bandwidth[dd] for dd in ddid])[:, 0]

    # Now get info from the subtables
    maps_data = list()
    for channum in range(channels):
        try:
            vis = ms.getcol('DATA')[:, channum, :]
        except IndexError:
            raise IndexError("channel number exceeds max. within ms")
    
        frequency = numpy.array([cfrequency[dd] for dd in ddid])[:, channum]
        uvw *= frequency[:, numpy.newaxis] / constants.c.to('m/s').value
        
        vis_list = Visibility(uvw=uvw, time=time, antenna1=antenna1, antenna2=antenna2,
                              frequency=frequency, vis=vis,
                              weight=weight, imaging_weight=weight,
                              integration_time=integration_time,
                              channel_bandwidth=channel_bandwidth,
                              configuration=configuration,
                              phasecentre=phasecentre,
                              polarisation_frame=polarisation_frame)

        maps_data.append(vis_list)

    return maps_data