示例#1
0
 def test_alias(self):
     self.cache = SensorCache(self._cache_data(),
                              timestamps=np.arange(10.),
                              dump_period=1.0,
                              aliases={'zz': 'at'})
     # Check that adding the alias didn't lead to extraction
     assert_is_instance(self.cache.get('czz', extract=False),
                        SimpleSensorGetter)
     np.testing.assert_array_equal(self.cache['czz'], self.cache['cat'])
示例#2
0
def create_sensor_cache(bandpass_parts=BANDPASS_PARTS):
    """Create a SensorCache for testing applycal sensors."""
    cache = {}
    cache['Observation/target'] = TARGET_SENSOR
    # Add delay product
    delays = create_product(create_delay)
    sensor = create_raw_sensor([3., 10.], [np.zeros_like(delays), delays])
    cache[CAL_STREAM + '_product_K'] = sensor
    # Add bandpass product (multi-part)
    bandpasses = create_product(create_bandpass)
    for part, bp in enumerate(np.split(bandpasses, bandpass_parts)):
        sensor = create_raw_sensor([2., 12.], [np.ones_like(bp), bp])
        cache[CAL_STREAM + '_product_B' + str(part)] = sensor
    # Add gain product (one value for entire band)
    gains = create_product(create_gain)
    sensor = create_raw_sensor(GAIN_EVENTS, gains)
    cache[CAL_STREAM + '_product_G'] = sensor
    # Add gain product (varying across frequency and time)
    gains = create_product(
        partial(create_gain, multi_channel=True, targets=True))
    sensor = create_raw_sensor(GAIN_EVENTS, gains)
    cache[CAL_STREAM + '_product_GPHASE'] = sensor
    # Construct sensor cache
    return SensorCache(cache,
                       timestamps=np.arange(N_DUMPS, dtype=float),
                       dump_period=1.,
                       props=SENSOR_PROPS)
示例#3
0
def get_tracks(data, telstate, dump_period):
    """Determine the start and end indices of each track segment in data buffer.

    Inputs
    ------
    data : dict
        Data buffer
    telstate : :class:`katsdptelstate.TelescopeState`
        The telescope state associated with this pipeline
    dump_period : float
        Dump period in seconds

    Returns
    -------
    segments : list of slice objects
        List of slices indicating dumps associated with each track in buffer
    """
    sensor_name = 'obs_activity'
    cache = {sensor_name: TelstateSensorGetter(telstate, sensor_name)}
    sensors = SensorCache(cache, data['times'], dump_period, props=SENSOR_PROPS)
    activity = sensors.get(sensor_name)
    return [segment for (segment, a) in activity.segments() if a == 'track']
示例#4
0
    def __init__(self, target, subarray, spectral_window, timestamps):
        super(MinimalDataSet, self).__init__(name='test', ref_ant='array')
        num_dumps = len(timestamps)
        num_chans = spectral_window.num_chans
        num_corrprods = len(subarray.corr_products)
        dump_period = timestamps[1] - timestamps[0]

        def constant_sensor(value):
            return CategoricalData([value], [0, num_dumps])

        self.subarrays = [subarray]
        self.spectral_windows = [spectral_window]
        sensors = {}
        for ant in subarray.ants:
            sensors['Antennas/%s/antenna' %
                    (ant.name, )] = constant_sensor(ant)
            az, el = target.azel(timestamps, ant)
            sensors['Antennas/%s/az' % (ant.name, )] = az
            sensors['Antennas/%s/el' % (ant.name, )] = el
        # Extract array reference position as 'array_ant' from last antenna
        array_ant_fields = ['array'] + ant.description.split(',')[1:5]
        array_ant = Antenna(','.join(array_ant_fields))
        sensors['Antennas/array/antenna'] = constant_sensor(array_ant)

        sensors['Observation/target'] = constant_sensor(target)
        for name in ('spw', 'subarray', 'scan', 'compscan', 'target'):
            sensors['Observation/%s_index' % (name, )] = constant_sensor(0)
        sensors['Observation/scan_state'] = constant_sensor('track')
        sensors['Observation/label'] = constant_sensor('track')

        self._timestamps = timestamps
        self._time_keep = np.full(num_dumps, True, dtype=np.bool_)
        self._freq_keep = np.full(num_chans, True, dtype=np.bool_)
        self._corrprod_keep = np.full(num_corrprods, True, dtype=np.bool_)
        self.dump_period = dump_period
        self.start_time = Timestamp(timestamps[0] - 0.5 * dump_period)
        self.end_time = Timestamp(timestamps[-1] + 0.5 * dump_period)
        self.sensor = SensorCache(sensors,
                                  timestamps,
                                  dump_period,
                                  keep=self._time_keep,
                                  virtual=DEFAULT_VIRTUAL_SENSORS)
        self.catalogue.add(target)
        self.catalogue.antenna = array_ant
        self.select(spw=0, subarray=0)
示例#5
0
 def _make_cache(timestamps, sensors):
     cache_data = {}
     for name, ts, values in sensors:
         sd = SimpleSensorGetter(name, np.asarray(ts), np.asarray(values))
         cache_data[name] = sd
     return SensorCache(cache_data, timestamps, 2.0)
示例#6
0
 def setup(self):
     self.cache = SensorCache(self._cache_data(),
                              timestamps=np.arange(10.),
                              dump_period=1.0)
示例#7
0
class TestSensorCache:
    def _cache_data(self):
        sensors = [('foo', [4.0, 7.0], [3.0, 6.0]),
                   ('cat', [2.0, 6.0], ['hello', 'world'])]
        cache_data = {}
        for name, ts, values in sensors:
            sd = SimpleSensorGetter(name, np.asarray(ts), np.asarray(values))
            cache_data[name] = sd
        return cache_data

    def setup(self):
        self.cache = SensorCache(self._cache_data(),
                                 timestamps=np.arange(10.),
                                 dump_period=1.0)

    def test_extract_float(self):
        data = self.cache.get('foo', extract=True)
        np.testing.assert_array_equal(
            data, [3.0, 3.0, 3.0, 3.0, 3.0, 4.0, 5.0, 6.0, 6.0, 6.0])

    def test_extract_categorical(self):
        data = self.cache.get('cat', extract=True)
        H = 'hello'
        W = 'world'
        np.testing.assert_array_equal(data[:], [H, H, H, H, H, H, W, W, W, W])

    def test_alias(self):
        self.cache = SensorCache(self._cache_data(),
                                 timestamps=np.arange(10.),
                                 dump_period=1.0,
                                 aliases={'zz': 'at'})
        # Check that adding the alias didn't lead to extraction
        assert_is_instance(self.cache.get('czz', extract=False),
                           SimpleSensorGetter)
        np.testing.assert_array_equal(self.cache['czz'], self.cache['cat'])

    def test_len(self):
        assert_equal(len(self.cache), 2)

    def test_keys(self):
        assert_equal(sorted(self.cache.keys()), ['cat', 'foo'])

    def test_contains(self):
        assert_in('cat', self.cache)
        assert_in('foo', self.cache)
        assert_not_in('dog', self.cache)
        template = 'Antennas/{ant}/{param1}_{param2}'
        self.cache.virtual[template] = lambda x: None
        assert_not_in(template, self.cache)

    def test_setitem_delitem(self):
        self.cache['bar'] = SimpleSensorGetter('bar', np.array([1.0]),
                                               np.array([0.0]))
        np.testing.assert_array_equal(self.cache['bar'], np.zeros(10))
        del self.cache['bar']
        assert_not_in('bar', self.cache)

    def test_sensor_time_offset(self):
        data = self.cache.get('foo', extract=True, time_offset=-1.0)
        np.testing.assert_array_equal(
            data, [3.0, 3.0, 3.0, 3.0, 4.0, 5.0, 6.0, 6.0, 6.0, 6.0])

    def test_virtual_sensors(self):
        calculate_value = Mock()

        def _check_sensor(cache, name, **kwargs):
            """Check that virtual sensor function gets the expected parameters."""
            assert_equal(kwargs, params)
            calculate_value()
            value = kwargs['param2']
            cache[name] = value
            return value

        # Set up a virtual sensor and trigger it to get a value
        params = {'ant': 'm000', 'param1': 'one', 'param2': 'two'}
        template = 'Antennas/{ant}/{param1}_{param2}'
        self.cache.virtual[template] = _check_sensor
        value = self.cache.get(template.format(**params))
        assert_equal(value, params['param2'])
        assert_equal(calculate_value.call_count, 1)
        # Check that the value was taken from the cache the second time around
        value = self.cache.get(template.format(**params))
        assert_equal(value, params['param2'])
        assert_equal(calculate_value.call_count, 1)
        # If your parameter values contain underscores, don't use it as delimiter
        params = {'ant': 'm000', 'param1': 'one', 'param2': 'two_three'}
        with assert_raises(AssertionError):
            self.cache.get(template.format(**params))
        template = 'Antennas/{ant}/{param1}/{param2}'
        # The updated template has not yet been added to the cache
        with assert_raises(KeyError):
            self.cache.get(template.format(**params))
        self.cache.virtual[template] = _check_sensor
        value = self.cache.get(template.format(**params))
        assert_equal(value, params['param2'])
        assert_equal(calculate_value.call_count, 2)
示例#8
0
    def __init__(self, **kwargs):
        """
        Parameters
        ----------
        timestamps (optional) : dict
            Dictionary defining the start time and dump rate of the observation.
            Defaults to the current time and 4 second dump rates.
        subarrays (optional): list of dict
            List of dictionaries, each defining a subarray.
        spws (optional): list of dict
            List of dictionaries, each defining a spectral window.
            Defaults to MeerKAT 32K L band
        dumps (optional): list of tuples
            List of (event, number of dumps, target) tuples
        vis (optional): function
            Custom function defining the visibilities returned by
            the MockDataSet instance.

            The function must take a MockDataSet instance as its first
            argument and should have the following signature:

            .. code-block:: python

                def my_vis(dataset):
                    return np.zeros(dataset.shape, dtype=np.complex64)

            If you wish to pass in data orthogonal to dataset ``functools.partial``
            can be used to construct a ``callable`` with the correct signature.

            .. code-block:: python

                def my_vis(dataset, my_data):
                    shape = dataset.shape
                    ...
                    return np.array(..., dtype=np.complex64)

                ds = MockDataSet(vis=partial(my_vis, my_data=...))

        weights (optional): function
            Function from which the weights array is defined.
            Similar to vis, should create an ndarray of float32 values.
        flags (optional): function
            Function from which the vis array is defined.
            Similar to vis, should create an ndarray of boolean values.
        """
        super(MockDataSet, self).__init__(name='mock')
        self.observer = 'mock'
        self.description = "Mock observation"

        # Obtain any custom instructions for builiding
        # the mock observation
        metadata_defs = kwargs.get('metadata', DEFAULT_METADATA)
        timestamp_defs = kwargs.get('timestamps', DEFAULT_TIMESTAMPS)
        subarray_defs = kwargs.get('subarrays', DEFAULT_SUBARRAYS)
        dump_defs = kwargs.get('dumps', DEFAULT_DUMPS)
        spw_defs = kwargs.get('spws', DEFAULT_SPWS)

        self._vis_def = kwargs.get('vis', DEFAULT_VIS)
        self._flags_def = kwargs.get('flags', DEFAULT_FLAGS)
        self._weights_def = kwargs.get('weights', DEFAULT_WEIGHTS)

        self._create_metadata(metadata_defs)
        self._create_timestamps(timestamp_defs, dump_defs)

        # Now create the sensors cache now that
        # we have dump period and timestamps
        self.sensor = SensorCache({},
                                  self._timestamps,
                                  self.dump_period,
                                  keep=self._time_keep,
                                  props=SENSOR_PROPS,
                                  virtual=VIRTUAL_SENSORS)

        self._create_subarrays(subarray_defs)
        self._create_spectral_windows(spw_defs)
        self._create_antenna_sensors(self.ants)

        try:
            ref_ant = self.ants[0]
        except IndexError:
            raise ValueError("No antenna were defined "
                             "for the default subarray")

        self._create_targets(dump_defs, ref_ant)
        self._create_scans(ref_ant, dump_defs)

        ncorrproducts = self.corr_products.shape[0]
        nchan = self.channels.shape[0]

        # Select everything upfront (weights + flags already set to all in superclass)
        self._time_keep = np.ones(self._ndumps, dtype=np.bool)
        self._corrprod_keep = np.ones(ncorrproducts, dtype=np.bool)
        self._freq_keep = np.ones(nchan, dtype=np.bool)
        self._create_azel_sensors()
        ants = [ant.name for ant in self.ants]
        self.select(ants=ants, spw=0, subarray=0)