コード例 #1
0
def simulate_gaintable(gt: GainTable, phase_error=0.1, amplitude_error=0.0, leakage=0.0) -> 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
    
    """
    log.info("simulate_gaintable: Simulating amplitude error = %.4f, phase error = %.4f"
             % (amplitude_error, phase_error))
    amp = 1.0
    phasor = 1.0
    if phase_error:
        phasor = numpy.exp(1j * numpy.random.normal(0, phase_error, gt.data['gain'].shape))
    if amplitude_error > 0.0:
        amp = numpy.random.lognormal(mean=0.0, sigma=amplitude_error, size=gt.data['gain'].shape)
    
    gt.data['gain'] = amp * phasor
    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
コード例 #3
0
 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
コード例 #5
0
ファイル: operations.py プロジェクト: acl-star/arlo
def create_gaintable_from_blockvisibility(vis: BlockVisibility,
                                          time_width: float = None,
                                          frequency_width: float = None,
                                          **kwargs) -> GainTable:
    """ Create gain table from visibility.
    
    This makes an empty gain table consistent with the BlockVisibility.
    
    :param vis: BlockVisibilty
    :param time_width: 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
    utimes = numpy.unique(vis.time)
    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
    gain_frequency = ufrequency
    gain_residual = numpy.zeros([ntimes, nfrequency, nrec, nrec])

    gt = GainTable(gain=gain,
                   time=gain_time,
                   weight=gain_weight,
                   residual=gain_residual,
                   frequency=gain_frequency,
                   receptor_frame=receptor_frame)

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

    return gt
コード例 #6
0
def create_gaintable_from_blockvisibility(vis: BlockVisibility,
                                          timeslice: float = 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':
        utimes = numpy.unique(vis.time)
        ntimes = len(utimes)
        gain_interval = numpy.zeros([ntimes])
        if ntimes > 1:
            gain_interval[:-1] = utimes[1:] - utimes[0:-1]
            gain_interval[-1] = utimes[-1] - utimes[-2]
        else:
            gain_interval[...] = 1.0

    else:
        ntimes = numpy.ceil((numpy.max(vis.time) - numpy.min(vis.time)) /
                            timeslice).astype('int')
        utimes = numpy.linspace(numpy.min(vis.time), numpy.max(vis.time),
                                ntimes)
        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
    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)

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

    return gt
コード例 #7
0
def gaintable_summary(gt: GainTable):
    """Return string summarizing the Gaintable

    """
    return "%s rows, %.3f GB" % (gt.data.shape, gt.size())
コード例 #8
0
def simulate_gaintable(gt: GainTable,
                       phase_error=0.1,
                       amplitude_error=0.0,
                       smooth_channels=1,
                       leakage=0.0,
                       seed=180555,
                       **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')

    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