def simulate_gaintable(gt: GainTable, phase_error=0.1, amplitude_error=0.0, smooth_channels=1,
                       leakage=0.0, seed=None, **kwargs) -> GainTable:
    """ Simulate a gain table
    
    :type gt: GainTable
    :param phase_error: std of normal distribution, zero mean
    :param amplitude_error: std of log normal distribution
    :param leakage: std of cross hand leakage
    :param seed: Seed for random numbers def: 180555
    :param smooth_channels: Use bspline over smooth_channels
    :param kwargs:
    :return: Gaintable
    
    """
    
    def moving_average(a, n=3):
        return numpy.convolve(a, numpy.ones((n,)) / n, mode='valid')
    
    if seed is not None:
        numpy.random.seed(seed)
    
    log.debug("simulate_gaintable: Simulating amplitude error = %.4f, phase error = %.4f"
              % (amplitude_error, phase_error))
    amps = 1.0
    phases = 1.0
    ntimes, nant, nchan, nrec, _ = gt.data['gain'].shape
    if phase_error > 0.0:
        phases = numpy.zeros(gt.data['gain'].shape)
        for time in range(ntimes):
            for ant in range(nant):
                phase = numpy.random.normal(0, phase_error, nchan + int(smooth_channels) - 1)
                if smooth_channels > 1:
                    phase = moving_average(phase, smooth_channels)
                phases[time, ant, ...] = phase[..., numpy.newaxis, numpy.newaxis]
    
    if amplitude_error > 0.0:
        amps = numpy.ones(gt.data['gain'].shape, dtype='complex')
        for time in range(ntimes):
            for ant in range(nant):
                amp = numpy.random.lognormal(mean=0.0, sigma=amplitude_error, size=nchan + int(smooth_channels) - 1)
                if smooth_channels > 1:
                    amp = moving_average(amp, smooth_channels)
                    amp = amp / numpy.average(amp)
                amps[time, ant, ...] = amp[..., numpy.newaxis, numpy.newaxis]
    
    gt.data['gain'] = amps * numpy.exp(0 + 1j * phases)
    nrec = gt.data['gain'].shape[-1]
    if nrec > 1:
        if leakage > 0.0:
            leak = numpy.random.normal(0, leakage, gt.data['gain'][..., 0, 0].shape) + 1j * \
                   numpy.random.normal(0, leakage, gt.data['gain'][..., 0, 0].shape)
            gt.data['gain'][..., 0, 1] = gt.data['gain'][..., 0, 0] * leak
            leak = numpy.random.normal(0, leakage, gt.data['gain'][..., 1, 1].shape) + 1j * \
                   numpy.random.normal(0, leakage, gt.data['gain'][..., 1, 1].shape)
            gt.data['gain'][..., 1, 0] = gt.data['gain'][..., 1, 1] * leak
        else:
            gt.data['gain'][..., 0, 1] = 0.0
            gt.data['gain'][..., 1, 0] = 0.0
    
    return gt
예제 #2
0
def create_gaintable_from_rows(gt: GainTable,
                               rows: numpy.ndarray,
                               makecopy=True) -> GainTable:
    """ Create a GainTable from selected rows

    :param gt: GainTable
    :param rows: Boolean array of row selection
    :param makecopy: Make a deep copy (True)
    :return: GainTable
    """

    if rows is None or numpy.sum(rows) == 0:
        return None

    assert len(
        rows
    ) == gt.ntimes, "Length of rows does not agree with length of GainTable"

    assert isinstance(gt, GainTable), gt

    if makecopy:
        newgt = copy_gaintable(gt)
        newgt.data = copy.deepcopy(gt.data[rows])
        return newgt
    else:
        gt.data = copy.deepcopy(gt.data[rows])

        return gt
 def test_create_gaintable_from_other(self):
     for timeslice in [10.0, 'auto', 1e5]:
         for spf, dpf in[('stokesIQUV', 'linear')]:
             self.actualSetup(spf, dpf)
             gt = create_gaintable_from_blockvisibility(self.vis, timeslice=timeslice)
             log.info("Created gain table: %s" % (gaintable_summary(gt)))
             new_gt = GainTable(data=gt.data)
             assert new_gt.data.shape == gt.data.shape
예제 #4
0
def append_gaintable(gt: GainTable, othergt: GainTable) -> GainTable:
    """Append othergt to gt

    :param gt:
    :param othergt:
    :return: GainTable gt + othergt
    """
    assert gt.receptor_frame == othergt.receptor_frame
    gt.data = numpy.hstack((gt.data, othergt.data))
    return gt
def helper_create_gaintable_object(c_gt, freqs, recframe):
    tgt = GainTable(data=None,
                    frequency=freqs,
                    gain=c_gt['gain'],
                    weight=c_gt['weight'],
                    residual=c_gt['residual'],
                    time=c_gt['time'],
                    interval=c_gt['interval'],
                    receptor_frame=recframe)
    #    print(tgt.__dict__)
    return tgt
예제 #6
0
def convert_hdf_to_gaintable(f):
    """ Convert HDF root to a GainTable

    :param f:
    :return:
    """
    assert f.attrs['ARL_data_model'] == "GainTable", "Not a GainTable"
    receptor_frame = ReceptorFrame(f.attrs['receptor_frame'])
    frequency = numpy.array(f.attrs['frequency'])
    data = numpy.array(f['data'])
    gt = GainTable(data=data, receptor_frame=receptor_frame, frequency=frequency)
    return gt
def convert_hdf_to_gaintable(f):
    """ Convert HDF root to a GainTable

    :param f:
    :return:
    """
    assert f.attrs['ARL_data_model'] == "GainTable", "Not a GainTable"
    receptor_frame = ReceptorFrame(f.attrs['receptor_frame'])
    frequency = numpy.array(f.attrs['frequency'])
    data = numpy.array(f['data'])
    s = f.attrs['phasecentre_coords'].split()
    ss = [float(s[0]), float(s[1])] * u.deg
    phasecentre = SkyCoord(ra=ss[0], dec=ss[1], frame=f.attrs['phasecentre_frame'])
    gt = GainTable(data=data, receptor_frame=receptor_frame, frequency=frequency, phasecentre=phasecentre)
    return gt
예제 #8
0
def create_gaintable_from_blockvisibility(vis: BlockVisibility,
                                          timeslice=None,
                                          frequencyslice: float = None,
                                          **kwargs) -> GainTable:
    """ Create gain table from visibility.
    
    This makes an empty gain table consistent with the BlockVisibility.
    
    :param vis: BlockVisibilty
    :param timeslice: Time interval between solutions (s)
    :param frequency_width: Frequency solution width (Hz)
    :return: GainTable
    
    """
    assert isinstance(
        vis, BlockVisibility), "vis is not a BlockVisibility: %r" % vis

    nants = vis.nants

    if timeslice is None or timeslice == 'auto':
        timeslice = numpy.min(vis.integration_time)

    utimes = timeslice * numpy.unique(
        numpy.round((vis.time - vis.time[0]) / timeslice))
    ntimes = len(utimes)
    gain_interval = timeslice * numpy.ones([ntimes])

    #    log.debug('create_gaintable_from_blockvisibility: times are %s' % str(utimes))
    #    log.debug('create_gaintable_from_blockvisibility: intervals are %s' % str(gain_interval))

    ntimes = len(utimes)
    ufrequency = numpy.unique(vis.frequency)
    nfrequency = len(ufrequency)

    receptor_frame = ReceptorFrame(vis.polarisation_frame.type)
    nrec = receptor_frame.nrec

    gainshape = [ntimes, nants, nfrequency, nrec, nrec]
    gain = numpy.ones(gainshape, dtype='complex')
    if nrec > 1:
        gain[..., 0, 1] = 0.0
        gain[..., 1, 0] = 0.0

    gain_weight = numpy.ones(gainshape)
    gain_time = utimes + vis.time[0]
    gain_frequency = ufrequency
    gain_residual = numpy.zeros([ntimes, nfrequency, nrec, nrec])

    gt = GainTable(gain=gain,
                   time=gain_time,
                   interval=gain_interval,
                   weight=gain_weight,
                   residual=gain_residual,
                   frequency=gain_frequency,
                   receptor_frame=receptor_frame,
                   phasecentre=vis.phasecentre,
                   configuration=vis.configuration)

    assert isinstance(gt, GainTable), "gt is not a GainTable: %r" % gt
    assert_vis_gt_compatible(vis, gt)

    return gt
예제 #9
0
def gaintable_summary(gt: GainTable):
    """Return string summarizing the Gaintable

    """
    return "%s rows, %.3f GB" % (gt.data.shape, gt.size())