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 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)
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']
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)
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)
def setup(self): self.cache = SensorCache(self._cache_data(), timestamps=np.arange(10.), dump_period=1.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)
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)