class TestImporter(): def setup_method(self, method): self.importer = MySubsetMaskImporter() self.importer.filename = 'test-filename' self.importer.reader = MagicMock() self.data = Data(x=[1, 2, 3]) self.data_collection = DataCollection([self.data]) def test_single_valid(self): self.importer.reader.return_value = OrderedDict([('subset 1', np.array([0, 1, 0]))]) self.importer.run(self.data, self.data_collection) assert len(self.data_collection.subset_groups) == 1 assert_equal(self.data.subsets[0].to_mask(), [0, 1, 0]) def test_multiple_valid(self): self.importer.reader.return_value = OrderedDict([('subset 1', np.array([0, 1, 0])), ('subset 2', np.array([1, 1, 0]))]) self.importer.run(self.data, self.data_collection) assert len(self.data_collection.subset_groups) == 2 assert_equal(self.data.subsets[0].to_mask(), [0, 1, 0]) assert_equal(self.data.subsets[1].to_mask(), [1, 1, 0]) def test_missing_masks(self): self.importer.reader.return_value = OrderedDict() with pytest.raises(ValueError) as exc: self.importer.run(self.data, self.data_collection) assert exc.value.args[0] == "No subset masks were returned" def test_single_invalid_shape(self): self.importer.reader.return_value = OrderedDict([('subset 1', np.array([0, 1, 0, 1]))]) with pytest.raises(ValueError) as exc: self.importer.run(self.data, self.data_collection) assert exc.value.args[0].replace('L', '') == "Mask shape (4,) does not match data shape (3,)" def test_multiple_inconsistent_shapes(self): self.importer.reader.return_value = OrderedDict([('subset 1', np.array([0, 1, 0])), ('subset 2', np.array([0, 1, 0, 1]))]) with pytest.raises(ValueError) as exc: self.importer.run(self.data, self.data_collection) assert exc.value.args[0] == "Not all subsets have the same shape" def test_subset_single(self): self.importer.reader.return_value = OrderedDict([('subset 1', np.array([0, 1, 0]))]) subset = self.data.new_subset() assert_equal(self.data.subsets[0].to_mask(), [0, 0, 0]) self.importer.run(subset, self.data_collection) assert_equal(self.data.subsets[0].to_mask(), [0, 1, 0]) def test_subset_multiple(self): self.importer.reader.return_value = OrderedDict([('subset 1', np.array([0, 1, 0])), ('subset 2', np.array([1, 1, 0]))]) subset = self.data.new_subset() with pytest.raises(ValueError) as exc: self.importer.run(subset, self.data_collection) assert exc.value.args[0] == 'Can only read in a single subset when importing into a subset'
def test_hdf5_writer_subset(tmpdir, dtype): filename = tmpdir.join('test').strpath data = Data(x=np.arange(6).reshape(2, 3).astype(dtype), y=(np.arange(6) * 2).reshape(2, 3).astype(dtype)) subset = data.new_subset() subset.subset_state = data.id['x'] > 2 hdf5_writer(filename, subset) from h5py import File f = File(filename) if np.dtype(dtype).kind == 'f': assert np.all(np.isnan(f['x'][0])) assert np.all(np.isnan(f['y'][0])) else: np.testing.assert_equal(f['x'][0], 0) np.testing.assert_equal(f['y'][0], 0) np.testing.assert_equal(f['x'][1], data['x'][1]) np.testing.assert_equal(f['y'][1], data['y'][1]) assert f['x'][()].dtype == dtype assert f['y'][()].dtype == dtype f.close()
def setup_method(self, method): x = np.arange(80).reshape(8, 10) d = Data(x=x, label='data') s = d.new_subset() s.subset_state = d.id['x'] > 30 print(s.to_mask()) self.subset = s self.x = x self.im = SubsetImage(s, np.s_[:, :]) m = (s.to_mask() * 127).astype(np.uint8) self.base = BaseImage.BaseImage(data_np=m)
def test_fits_writer_subset(tmpdir): filename = tmpdir.join('test').strpath data = Data(x=np.arange(6).reshape(2, 3), y=(np.arange(6) * 2).reshape(2, 3)) subset = data.new_subset() subset.subset_state = data.id['x'] > 2 fits_writer(filename, subset) with fits.open(filename) as hdulist: assert np.all(np.isnan(hdulist['x'].data[0])) assert np.all(np.isnan(hdulist['y'].data[0])) np.testing.assert_equal(hdulist['x'].data[1], data['x'][1]) np.testing.assert_equal(hdulist['y'].data[1], data['y'][1])
def test_make_data_file(): from astropy.table import Table # astropy.Table interface has changed across versions. Check # that we build a valid table d = Data(x=[1, 2, 3], y=[2, 3, 4], label='data') s = d.new_subset(label='test') s.subset_state = d.id['x'] > 1 dir = mkdtemp() try: make_data_file(d, (s,), dir) t = Table.read(os.path.join(dir, 'data.csv'), format='ascii') np.testing.assert_array_equal(t['x'], [1, 2, 3]) np.testing.assert_array_equal(t['y'], [2, 3, 4]) np.testing.assert_array_equal(t['selection_0'], [0, 1, 1]) finally: rmtree(dir, ignore_errors=True)
def test_hdf5_writer_subset(tmpdir): filename = tmpdir.join('test').strpath data = Data(x=np.arange(6).reshape(2, 3).astype(float), y=(np.arange(6) * 2).reshape(2, 3).astype(float)) subset = data.new_subset() subset.subset_state = data.id['x'] > 2 hdf5_writer(filename, subset) from h5py import File f = File(filename) assert np.all(np.isnan(f['x'].value[0])) assert np.all(np.isnan(f['y'].value[0])) np.testing.assert_equal(f['x'].value[1], data['x'][1]) np.testing.assert_equal(f['y'].value[1], data['y'][1]) f.close()
def test_fits_writer_subset(tmpdir, dtype): filename = tmpdir.join('test').strpath data = Data(x=np.arange(6).reshape(2, 3).astype(dtype), y=(np.arange(6) * 2).reshape(2, 3).astype(dtype)) subset = data.new_subset() subset.subset_state = data.id['x'] > 2 fits_writer(filename, subset) with fits.open(filename) as hdulist: assert np.all(np.isnan(hdulist['x'].data[0])) assert np.all(np.isnan(hdulist['y'].data[0])) np.testing.assert_equal(hdulist['x'].data[1], data['x'][1]) np.testing.assert_equal(hdulist['y'].data[1], data['y'][1]) # Here we check BITPIX, not the dtype of the read in data, because if # BLANK is present, astropy.io.fits scales the data to float. We want to # just make sure here the data is stored with the correct type on disk. assert hdulist['x'].header['BITPIX'] == BITPIX[dtype] assert hdulist['y'].header['BITPIX'] == BITPIX[dtype]
def setup_method(self, method): d = Data(x=[1, 2, 3, 4, 5], c=['a', 'b', 'a', 'a', 'b'], label='test') s = d.new_subset() s.subset_state = d.id['x'] > 2 self.d = d self.s = s
class TestWWTDataViewer(object): def setup_method(self, method): self.d = Data(x=[1, 2, 3], y=[2, 3, 4], z=[4, 5, 6]) self.application = GlueApplication() self.dc = self.application.data_collection self.dc.append(self.d) self.hub = self.dc.hub self.session = self.application.session self.viewer = self.application.new_data_viewer(WWTQtViewerBlocking) self.options = self.viewer.options_widget() def teardown_method(self, method): self.viewer.close(warn=False) self.viewer = None self.application.close() self.application = None def register(self): self.viewer.register_to_hub(self.hub) def test_add_data(self): self.viewer.add_data(self.d) self.viewer.state.lon_att = self.d.id['x'] self.viewer.state.lat_att = self.d.id['y'] def test_center(self): self.viewer.add_data(self.d) self.viewer.state.lon_att = self.d.id['x'] self.viewer.state.lat_att = self.d.id['y'] self.viewer.layers[0].center() def test_new_subset_group(self): # Make sure only the subset for data that is already inside the viewer # is added. d2 = Data(a=[4, 5, 6]) self.dc.append(d2) self.viewer.add_data(self.d) assert len(self.viewer.layers) == 1 self.dc.new_subset_group(subset_state=self.d.id['x'] > 1, label='A') assert len(self.viewer.layers) == 2 def test_double_add_ignored(self): assert len(self.viewer.layers) == 0 self.viewer.add_data(self.d) assert len(self.viewer.layers) == 1 self.viewer.add_data(self.d) assert len(self.viewer.layers) == 1 def test_remove_data(self): self.register() self.viewer.add_data(self.d) layer = self.viewer._layer_artist_container[self.d][0] layer.clear = MagicMock() self.hub.broadcast( message.DataCollectionDeleteMessage(self.dc, data=self.d)) # TODO: the following currently fails but is not critical, so we # skip for now. # assert layer.clear.call_count == 1 assert self.d not in self.viewer._layer_artist_container def test_remove_subset(self): self.register() s = self.d.new_subset() self.viewer.add_subset(s) layer = self.viewer._layer_artist_container[s][0] layer.clear = MagicMock() self.hub.broadcast(message.SubsetDeleteMessage(s)) # assert layer.clear.call_count == 1 assert s not in self.viewer._layer_artist_container def test_subsets_added_with_data(self): s = self.d.new_subset() self.viewer.add_data(self.d) assert s in self.viewer._layer_artist_container def test_subsets_live_added(self): self.register() self.viewer.add_data(self.d) s = self.d.new_subset() assert s in self.viewer._layer_artist_container def test_clone(self): self.viewer.add_data(self.d) self.viewer.state.layers[0].ra_att = self.d.id['y'] self.viewer.state.layers[0].dec_att = self.d.id['x'] application2 = clone(self.application) application2.viewers[0][0] def test_changing_alt_back_to_none(self): # Regression test for a bug which caused an exception to # happen when changing the altitude attribute back to None self.viewer.add_data(self.d) self.viewer.state.mode = 'Milky Way' self.viewer.state.lon_att = self.d.id['x'] self.viewer.state.lat_att = self.d.id['y'] self.viewer.state.alt_att = self.d.id['z'] self.viewer.state.alt_unit = 'kpc' self.viewer.state.alt_att = None def test_remove_layer(self): # Make sure that _update_markers doesn't get called after removing a # layer. This is a regression test for # https://github.com/glue-viz/glue-wwt/issues/54 self.register() self.d.add_subset(self.d.id['x'] > 1) self.viewer.add_data(self.d) assert len(self.viewer.layers) == 2 subset_layer = self.viewer.layers[1] subset_layer.wwt_client.layers.add_table_layer = MagicMock() self.viewer.remove_subset(self.d.subsets[0]) assert len(self.viewer.layers) == 1 assert subset_layer.wwt_client.layers.add_table_layer.call_count == 0 assert subset_layer.wwt_layer is None @pytest.mark.skipif(sys.platform == 'win32', reason="Test causes issues on Windows") def test_save_tour(self, tmpdir): filename = tmpdir.join('mytour.wtt').strpath self.viewer.add_data(self.d) with patch.object(compat, 'getsavefilename', return_value=(filename, None)): self.viewer.toolbar.tools['save'].subtools[1].activate() assert os.path.exists(filename) with io.open(filename, newline='') as f: assert f.read().startswith( "<?xml version='1.0' encoding='UTF-8'?>\r\n<FileCabinet") def test_load_session_back_compat(self): # Make sure that old session files continue to work app = GlueApplication.restore_session( os.path.join(DATA, 'wwt_simple.glu')) viewer_state = app.viewers[0][0].state assert viewer_state.lon_att.label == 'a' assert viewer_state.lat_att.label == 'b' assert viewer_state.frame == 'Galactic'
class TestDendroClient(): def setup_method(self, method): self.data = Data(parent=[4, 4, 5, 5, 5, -1], height=[5, 4, 3, 2, 1, 0], label='dendro') self.dc = DataCollection([self.data]) self.hub = self.dc.hub self.client = DendroClient(self.dc, figure=FIGURE) EditSubsetMode().data_collection = self.dc def add_subset_via_hub(self): self.connect() self.client.add_layer(self.data) s = self.data.new_subset() return s def connect(self): self.client.register_to_hub(self.hub) self.dc.register_to_hub(self.hub) def click(self, x, y): roi = PointROI(x=x, y=y) self.client.apply_roi(roi) def test_data_present_after_adding(self): assert self.data not in self.client self.client.add_layer(self.data) assert self.data in self.client def test_add_data_adds_subsets(self): s1 = self.data.new_subset() self.client.add_layer(self.data) assert s1 in self.client def test_remove_data(self): self.client.add_layer(self.data) self.client.remove_layer(self.data) assert self.data not in self.client def test_remove_data_removes_subsets(self): s = self.data.new_subset() self.client.add_layer(self.data) self.client.remove_layer(self.data) assert s not in self.client def test_add_subset_hub(self): s = self.add_subset_via_hub() assert s in self.client def test_new_subset_autoadd(self): self.connect() self.client.add_layer(self.data) s = self.data.new_subset() assert s in self.client def test_remove_subset_hub(self): s = self.add_subset_via_hub() s.delete() assert s not in self.client def test_subset_sync(self): s = self.add_subset_via_hub() self.client._update_layer = MagicMock() s.style.color = 'blue' self.client._update_layer.assert_called_once_with(s) def test_data_sync(self): self.connect() self.client.add_layer(self.data) self.client._update_layer = MagicMock() self.data.style.color = 'blue' self.client._update_layer.assert_called_once_with(self.data) def test_data_remove(self): s = self.add_subset_via_hub() self.dc.remove(self.data) assert self.data not in self.dc assert self.data not in self.client assert s not in self.client def test_log(self): self.client.ylog = True assert self.client.axes.get_yscale() == 'log' def test_1d_data_required(self): d = Data(x=[[1, 2], [2, 3]]) self.dc.append(d) self.client.add_layer(d) assert d not in self.client def test_apply_roi(self): self.client.add_layer(self.data) self.client.select_substruct = False self.click(0, 4) s = self.data.subsets[0] assert_array_equal(s.to_index_list(), [1]) self.click(0, 3) assert_array_equal(s.to_index_list(), [1]) self.click(0, 0) assert_array_equal(s.to_index_list(), [4]) self.click(.75, 4) assert_array_equal(s.to_index_list(), [0]) self.click(0, 10) assert_array_equal(s.to_index_list(), []) def test_apply_roi_children_select(self): self.client.select_substruct = True self.client.add_layer(self.data) self.click(.5, .5) s = self.data.subsets[0] assert_array_equal(s.to_index_list(), [0, 1, 4]) def test_attribute_change_triggers_relayout(self): self.client.add_layer(self.data) l = self.client._layout self.client.height_attr = self.data.id['parent'] assert self.client._layout is not l l = self.client._layout self.client.parent_attr = self.data.id['height'] assert self.client._layout is not l l = self.client._layout self.client.order_attr = self.data.id['parent'] assert self.client._layout is not l
class TestProfileViewerState: def setup_method(self, method): self.data = Data(label='d1') self.data.coords = SimpleCoordinates() self.data['x'] = np.arange(24).reshape((3, 4, 2)).astype(float) self.viewer_state = ProfileViewerState() self.layer_state = ProfileLayerState(viewer_state=self.viewer_state, layer=self.data) self.viewer_state.layers.append(self.layer_state) self.viewer_state.function = 'mean' def test_basic(self): x, y = self.layer_state.profile assert_allclose(x, [0, 2, 4]) assert_allclose(y, [3.5, 11.5, 19.5]) def test_basic_world(self): self.viewer_state.x_att = self.data.world_component_ids[0] x, y = self.layer_state.profile assert_allclose(x, [0, 2, 4]) assert_allclose(y, [3.5, 11.5, 19.5]) def test_x_att(self): self.viewer_state.x_att = self.data.pixel_component_ids[0] x, y = self.layer_state.profile assert_allclose(x, [0, 1, 2]) assert_allclose(y, [3.5, 11.5, 19.5]) self.viewer_state.x_att = self.data.pixel_component_ids[1] x, y = self.layer_state.profile assert_allclose(x, [0, 1, 2, 3]) assert_allclose(y, [8.5, 10.5, 12.5, 14.5]) self.viewer_state.x_att = self.data.pixel_component_ids[2] x, y = self.layer_state.profile assert_allclose(x, [0, 1]) assert_allclose(y, [11, 12]) def test_function(self): self.viewer_state.function = 'mean' x, y = self.layer_state.profile assert_allclose(y, [3.5, 11.5, 19.5]) self.viewer_state.function = 'minimum' x, y = self.layer_state.profile assert_allclose(y, [0, 8, 16]) self.viewer_state.function = 'maximum' x, y = self.layer_state.profile assert_allclose(y, [7, 15, 23]) self.viewer_state.function = 'sum' x, y = self.layer_state.profile assert_allclose(y, [28, 92, 156]) self.viewer_state.function = 'median' x, y = self.layer_state.profile assert_allclose(y, [3.5, 11.5, 19.5]) def test_subset(self): subset = self.data.new_subset() subset.subset_state = self.data.id['x'] > 10 self.layer_state.layer = subset x, y = self.layer_state.profile assert_allclose(x, [0, 2, 4]) assert_allclose(y, [np.nan, 13., 19.5]) subset.subset_state = self.data.id['x'] > 100 # TODO: the fact we have to call this isn't ideal self.layer_state.reset_cache() x, y = self.layer_state.profile assert len(x) == 0 assert len(y) == 0 def test_clone(self): self.viewer_state.x_att = self.data.pixel_component_ids[1] self.viewer_state.function = 'median' self.layer_state.attribute = self.data.id['x'] self.layer_state.linewidth = 3 viewer_state_new = clone(self.viewer_state) assert viewer_state_new.x_att.label == 'Pixel Axis 1 [y]' assert viewer_state_new.function == 'median' assert self.layer_state.attribute.label == 'x' assert self.layer_state.linewidth == 3 def test_limits(self): self.viewer_state.x_att = self.data.pixel_component_ids[0] assert self.viewer_state.x_min == -0.5 assert self.viewer_state.x_max == 2.5 self.viewer_state.flip_x() assert self.viewer_state.x_min == 2.5 assert self.viewer_state.x_max == -0.5 self.viewer_state.x_min = 1 self.viewer_state.x_max = 1.5 assert self.viewer_state.x_min == 1 assert self.viewer_state.x_max == 1.5 self.viewer_state.reset_limits() assert self.viewer_state.x_min == -0.5 assert self.viewer_state.x_max == 2.5
class TestHistogramLayerArtist(object): def setup_method(self, method): self.viewer_state = HistogramViewerState() ax = plt.subplot(1, 1, 1) self.data = Data(x=[1, 2, 3], y=[2, 3, 4]) self.subset = self.data.new_subset() self.subset.subset_state = self.data.id['x'] > 1 dc = DataCollection([self.data]) # TODO: The following line shouldn't be needed self.viewer_state.data_collection = dc self.artist = HistogramLayerArtist(ax, self.viewer_state, layer=self.subset) self.layer_state = self.artist.state self.viewer_state.layers.append(self.layer_state) self.call_counter = CallCounter() sys.setprofile(self.call_counter) def teardown_method(self, method): self.artist.remove() sys.setprofile(None) def test_recalc_on_state_changes(self): assert self.call_counter['_calculate_histogram'] == 0 assert self.call_counter['_update_artists'] == 0 # attribute self.viewer_state.x_att = self.data.id['y'] assert self.call_counter['_calculate_histogram'] == 1 assert self.call_counter['_update_artists'] == 1 # lo self.viewer_state.hist_x_min = -1 assert self.call_counter['_calculate_histogram'] == 2 assert self.call_counter['_update_artists'] == 2 # hi self.viewer_state.hist_x_max = 5 assert self.call_counter['_calculate_histogram'] == 3 assert self.call_counter['_update_artists'] == 3 # nbins self.viewer_state.hist_n_bin += 1 assert self.call_counter['_calculate_histogram'] == 4 assert self.call_counter['_update_artists'] == 4 # xlog self.viewer_state.x_log ^= True assert self.call_counter['_calculate_histogram'] == 5 assert self.call_counter['_update_artists'] == 5 # TODO: find a way to determine whether the histogram calculation is # carried out since _calculate_histogram calls are no longer a good # way to find out (we now rely on state cache) # ylog -- no call self.viewer_state.y_log ^= True # assert self.call_counter['_calculate_histogram'] == 5 assert self.call_counter['_update_artists'] == 6 # cumulative -- no call self.viewer_state.cumulative ^= True # assert self.call_counter['_calculate_histogram'] == 5 assert self.call_counter['_update_artists'] == 7 # normed -- no call self.viewer_state.normalize ^= True # assert self.call_counter['_calculate_histogram'] == 5 assert self.call_counter['_update_artists'] == 8 # subset style -- no call self.subset.style.color = '#00ff00' # assert self.call_counter['_calculate_histogram'] == 5 assert self.call_counter['_update_artists'] == 8
class TestWWTDataViewer(object): def setup_method(self, method): self.d = Data(x=[1, 2, 3], y=[2, 3, 4], z=[4, 5, 6]) self.application = GlueApplication() self.dc = self.application.data_collection self.dc.append(self.d) self.hub = self.dc.hub self.session = self.application.session self.viewer = self.application.new_data_viewer(WWTDataViewer) self.options = self.viewer.options_widget() def register(self): self.viewer.register_to_hub(self.hub) def test_add_data(self): self.viewer.add_data(self.d) self.viewer.state.lon_att = self.d.id['x'] self.viewer.state.lat_att = self.d.id['y'] def test_center(self): self.viewer.add_data(self.d) self.viewer.state.lon_att = self.d.id['x'] self.viewer.state.lat_att = self.d.id['y'] self.viewer.layers[0].center() def test_new_subset_group(self): # Make sure only the subset for data that is already inside the viewer # is added. d2 = Data(a=[4, 5, 6]) self.dc.append(d2) self.viewer.add_data(self.d) assert len(self.viewer.layers) == 1 self.dc.new_subset_group(subset_state=self.d.id['x'] > 1, label='A') assert len(self.viewer.layers) == 2 def test_double_add_ignored(self): assert len(self.viewer.layers) == 0 self.viewer.add_data(self.d) assert len(self.viewer.layers) == 1 self.viewer.add_data(self.d) assert len(self.viewer.layers) == 1 def test_remove_data(self): self.register() self.viewer.add_data(self.d) layer = self.viewer._layer_artist_container[self.d][0] layer.clear = MagicMock() self.hub.broadcast(message.DataCollectionDeleteMessage(self.dc, data=self.d)) # TODO: the following currently fails but is not critical, so we # skip for now. # assert layer.clear.call_count == 1 assert self.d not in self.viewer._layer_artist_container def test_remove_subset(self): self.register() s = self.d.new_subset() self.viewer.add_subset(s) layer = self.viewer._layer_artist_container[s][0] layer.clear = MagicMock() self.hub.broadcast(message.SubsetDeleteMessage(s)) #assert layer.clear.call_count == 1 assert s not in self.viewer._layer_artist_container def test_subsets_added_with_data(self): s = self.d.new_subset() self.viewer.add_data(self.d) assert s in self.viewer._layer_artist_container def test_subsets_live_added(self): self.register() self.viewer.add_data(self.d) s = self.d.new_subset() assert s in self.viewer._layer_artist_container def test_clone(self): self.viewer.add_data(self.d) self.viewer.state.layers[0].ra_att = self.d.id['y'] self.viewer.state.layers[0].dec_att = self.d.id['x'] application2 = clone(self.application) viewer2 = application2.viewers[0][0] def test_changing_alt_back_to_none(self): # Regression test for a bug which caused an exception to # happen when changing the altitude attribute back to None self.viewer.add_data(self.d) self.viewer.state.mode = 'Milky Way' self.viewer.state.lon_att = self.d.id['x'] self.viewer.state.lat_att = self.d.id['y'] self.viewer.state.alt_att = self.d.id['z'] self.viewer.state.alt_unit = 'kpc' self.viewer.state.alt_att = None
class TestWWTDataViewer(object): def setup_method(self, method): self.d = Data(x=[1, 2, 3], y=[2, 3, 4], z=[4, 5, 6]) self.application = GlueApplication() self.dc = self.application.data_collection self.dc.append(self.d) self.hub = self.dc.hub self.session = self.application.session self.viewer = self.application.new_data_viewer(WWTDataViewer) self.options = self.viewer.options_widget() def register(self): self.viewer.register_to_hub(self.hub) def test_add_data(self): self.viewer.add_data(self.d) self.viewer.state.lon_att = self.d.id['x'] self.viewer.state.lat_att = self.d.id['y'] def test_center(self): self.viewer.add_data(self.d) self.viewer.state.lon_att = self.d.id['x'] self.viewer.state.lat_att = self.d.id['y'] self.viewer.layers[0].center() def test_new_subset_group(self): # Make sure only the subset for data that is already inside the viewer # is added. d2 = Data(a=[4, 5, 6]) self.dc.append(d2) self.viewer.add_data(self.d) assert len(self.viewer.layers) == 1 self.dc.new_subset_group(subset_state=self.d.id['x'] > 1, label='A') assert len(self.viewer.layers) == 2 def test_double_add_ignored(self): assert len(self.viewer.layers) == 0 self.viewer.add_data(self.d) assert len(self.viewer.layers) == 1 self.viewer.add_data(self.d) assert len(self.viewer.layers) == 1 def test_remove_data(self): self.register() self.viewer.add_data(self.d) layer = self.viewer._layer_artist_container[self.d][0] layer.clear = MagicMock() self.hub.broadcast( message.DataCollectionDeleteMessage(self.dc, data=self.d)) # TODO: the following currently fails but is not critical, so we # skip for now. # assert layer.clear.call_count == 1 assert self.d not in self.viewer._layer_artist_container def test_remove_subset(self): self.register() s = self.d.new_subset() self.viewer.add_subset(s) layer = self.viewer._layer_artist_container[s][0] layer.clear = MagicMock() self.hub.broadcast(message.SubsetDeleteMessage(s)) #assert layer.clear.call_count == 1 assert s not in self.viewer._layer_artist_container def test_subsets_added_with_data(self): s = self.d.new_subset() self.viewer.add_data(self.d) assert s in self.viewer._layer_artist_container def test_subsets_live_added(self): self.register() self.viewer.add_data(self.d) s = self.d.new_subset() assert s in self.viewer._layer_artist_container def test_clone(self): self.viewer.add_data(self.d) self.viewer.state.layers[0].ra_att = self.d.id['y'] self.viewer.state.layers[0].dec_att = self.d.id['x'] application2 = clone(self.application) viewer2 = application2.viewers[0][0] def test_changing_alt_back_to_none(self): # Regression test for a bug which caused an exception to # happen when changing the altitude attribute back to None self.viewer.add_data(self.d) self.viewer.state.mode = 'Milky Way' self.viewer.state.lon_att = self.d.id['x'] self.viewer.state.lat_att = self.d.id['y'] self.viewer.state.alt_att = self.d.id['z'] self.viewer.state.alt_unit = 'kpc' self.viewer.state.alt_att = None def test_remove_layer(self): # Make sure that _update_markers doesn't get called after removing a # layer. This is a regression test for # https://github.com/glue-viz/glue-wwt/issues/54 self.register() self.d.add_subset(self.d.id['x'] > 1) self.viewer.add_data(self.d) assert len(self.viewer.layers) == 2 subset_layer = self.viewer.layers[1] subset_layer.wwt_client.layers.add_table_layer = MagicMock() self.viewer.remove_subset(self.d.subsets[0]) assert len(self.viewer.layers) == 1 assert subset_layer.wwt_client.layers.add_table_layer.call_count == 0 assert subset_layer.wwt_layer is None
class TestProfileViewer(object): def setup_method(self, method): self.data = Data(label='d1') self.data.coords = SimpleCoordinates() self.data['x'] = np.arange(24).reshape((3, 4, 2)) self.app = GlueApplication() self.session = self.app.session self.hub = self.session.hub self.data_collection = self.session.data_collection self.data_collection.append(self.data) self.viewer = self.app.new_data_viewer(ProfileViewer) def teardown_method(self, method): self.viewer.close() self.viewer = None self.app.close() self.app = None def test_functions(self): self.viewer.add_data(self.data) self.viewer.state.function = 'mean' assert len(self.viewer.layers) == 1 layer_artist = self.viewer.layers[0] assert_allclose(layer_artist.state.profile[0], [0, 2, 4]) assert_allclose(layer_artist.state.profile[1], [3.5, 11.5, 19.5]) def test_incompatible(self): self.viewer.add_data(self.data) data2 = Data(y=np.random.random((3, 4, 2))) self.data_collection.append(data2) self.viewer.add_data(data2) assert len(self.viewer.layers) == 2 assert self.viewer.layers[0].enabled assert not self.viewer.layers[1].enabled def test_selection(self): self.viewer.add_data(self.data) self.viewer.state.x_att = self.data.pixel_component_ids[0] roi = XRangeROI(0.9, 2.1) self.viewer.apply_roi(roi) assert len(self.data.subsets) == 1 assert_equal(self.data.subsets[0].to_mask()[:, 0, 0], [0, 1, 1]) self.viewer.state.x_att = self.data.world_component_ids[0] roi = XRangeROI(1.9, 3.1) self.viewer.apply_roi(roi) assert len(self.data.subsets) == 1 assert_equal(self.data.subsets[0].to_mask()[:, 0, 0], [0, 1, 0]) def test_enabled_layers(self): data2 = Data(label='d1', y=np.arange(24).reshape((3, 4, 2))) self.data_collection.append(data2) self.viewer.add_data(self.data) self.viewer.add_data(data2) assert self.viewer.layers[0].enabled assert not self.viewer.layers[1].enabled self.data_collection.add_link(ComponentLink([data2.world_component_ids[1]], self.data.world_component_ids[0], using=lambda x: 2 * x)) assert self.viewer.layers[0].enabled assert self.viewer.layers[1].enabled def test_slice_subset_state(self): self.viewer.add_data(self.data) subset = self.data.new_subset() subset.subset_state = SliceSubsetState(self.data, [slice(1, 2), slice(None)]) assert self.viewer.layers[0].enabled assert self.viewer.layers[1].enabled def test_clone(self): # Regression test for a bug that meant that deserializing a profile # viewer resulted in disabled layers self.viewer.add_data(self.data) subset = self.data.new_subset() subset.subset_state = SliceSubsetState(self.data, [slice(1, 2), slice(None)]) app = clone(self.app) assert app.viewers[0][0].layers[0].enabled assert app.viewers[0][0].layers[1].enabled app.close() def test_incompatible_on_add(self): # Regression test for a bug when adding a dataset to a profile viewer # with a single incompatible subset. subset_state = SliceSubsetState(self.data, [slice(1, 2), slice(None)]) self.data_collection.new_subset_group(subset_state=subset_state, label='s1') data2 = Data(x=[[2, 3], [4, 3]], label='d2') self.data_collection.append(data2) self.viewer.add_data(data2)
class MyClient(HubListener): def register_to_hub(self, hub): """ Sign up to receive DataMessages from the hub """ hub.subscribe(self, # subscribing object DataMessage, # message type to subscribe to handler=self.receive_message) # method to call def receive_message(self, message): """ Receives each DataMessage relay """ print(" MyClient received a message \n") # create objects client = MyClient() data = Data() subset = data.new_subset() data_collection = DataCollection() # connect them to each other hub = data_collection.hub data_collection.append(data) client.register_to_hub(hub) # manually send a DataMessage. Relayed to MyClient print('Manually sending DataMessage') message = DataMessage(data) hub.broadcast(message) # modify the data object. Automatically generates a DataMessage print('Automatically triggering DataMessage') data.label = "New label"
""" Sign up to receive DataMessages from the hub """ hub.subscribe(self, # subscribing object DataMessage, # message type to subscribe to handler = self.receive_message) # method to call def receive_message(self, message): """ Receives each DataMessage relay """ print " MyClient received a message \n" # create objects hub = Hub() client = MyClient() data = Data() subset = data.new_subset() data_collection = DataCollection() # connect them to each other data_collection.append(data) data_collection.register_to_hub(hub) client.register_to_hub(hub) # manually send a DataMessage. Relayed to MyClient print 'Manually sending DataMessage' message = DataMessage(data) hub.broadcast(message) #modify the data object. Automatically generates a DataMessage print 'Automatically triggering DataMessage' data.label = "New label"
class TestWWTDataViewer(object): def setup_method(self, method): self.d = Data(x=[1, 2, 3], y=[2, 3, 4]) self.dc = DataCollection([self.d]) self.hub = self.dc.hub self.session = Session(data_collection=self.dc, hub=self.hub) self.widget = WWTDataViewer(self.session, webdriver_class=MagicMock) self.options = self.widget.options_widget() def register(self): self.widget.register_to_hub(self.hub) def test_add_data(self): self.widget.add_data(self.d) self.options.ra_att = self.d.id['x'], self.d self.options.dec_att = self.d.id['y'], self.d assert self.d in self.widget def test_double_add_ignored(self): assert len(self.widget) == 0 self.widget.add_data(self.d) assert len(self.widget) == 1 self.widget.add_data(self.d) assert len(self.widget) == 1 def test_updated_on_data_update_message(self): self.register() self.widget.add_data(self.d) layer = self.widget._layer_artist_container[self.d][0] layer.update = MagicMock() self.d.style.color = 'green' assert layer.update.call_count == 1 def test_updated_on_subset_update_message(self): self.register() s = self.d.new_subset() self.widget.add_subset(s) layer = self.widget._layer_artist_container[s][0] layer.update = MagicMock() s.style.color = 'green' assert layer.update.call_count == 1 def test_remove_data(self): self.register() self.widget.add_data(self.d) layer = self.widget._layer_artist_container[self.d][0] layer.clear = MagicMock() self.hub.broadcast(message.DataCollectionDeleteMessage(self.dc, data=self.d)) # TODO: the following currently fails but is not critical, so we # skip for now. # assert layer.clear.call_count == 1 assert self.d not in self.widget def test_remove_subset(self): self.register() s = self.d.new_subset() self.widget.add_subset(s) layer = self.widget._layer_artist_container[s][0] layer.clear = MagicMock() self.hub.broadcast(message.SubsetDeleteMessage(s)) assert layer.clear.call_count == 1 assert self.d not in self.widget def test_subsets_added_with_data(self): s = self.d.new_subset() self.widget.add_data(self.d) assert s in self.widget def test_subsets_live_added(self): self.register() self.widget.add_data(self.d) s = self.d.new_subset() assert s in self.widget # TODO: determine if the following test is the desired behavior # def test_subsets_not_live_added_if_data_not_present(self): # self.register() # s = self.d.new_subset() # assert s not in self.widget def test_updated_on_add(self): self.register() self.widget._update_layer = MagicMock() self.widget.add_data(self.d) # TODO: ideally, the following should be called exactly once assert self.widget._update_layer.call_count >= 1 def test_updated_on_coordinate_change(self): self.register() self.widget.add_data(self.d) self.options.ra_att = self.d.id['x'], self.d self.options.dec_att = self.d.id['y'], self.d artist = self.widget._layer_artist_container[self.d][0] self.widget._update_layer = MagicMock() self.options.ra_att = self.d.id['y'], self.d self.widget._update_layer.call_count > 0
class TestWWTDataViewer(object): def setup_method(self, method): self.d = Data(x=[1, 2, 3], y=[2, 3, 4]) self.dc = DataCollection([self.d]) self.hub = self.dc.hub self.session = Session(data_collection=self.dc, hub=self.hub) self.widget = WWTDataViewer(self.session) self.widget.register_to_hub(self.hub) self.options = self.widget.options_widget() def register(self): self.widget.register_to_hub(self.hub) def test_add_data(self): self.widget.add_data(self.d) self.widget.state.layers[0].ra_att = self.d.id['x'] self.widget.state.layers[0].dec_att = self.d.id['y'] def test_center(self): self.widget.add_data(self.d) self.widget.state.layers[0].ra_att = self.d.id['x'] self.widget.state.layers[0].dec_att = self.d.id['y'] self.widget.layers[0].center() def test_new_subset_group(self): # Make sure only the subset for data that is already inside the viewer # is added. d2 = Data(a=[4, 5, 6]) self.dc.append(d2) self.widget.add_data(self.d) assert len(self.widget.layers) == 1 self.dc.new_subset_group(subset_state=self.d.id['x'] > 1, label='A') assert len(self.widget.layers) == 2 def test_double_add_ignored(self): assert len(self.widget.layers) == 0 self.widget.add_data(self.d) assert len(self.widget.layers) == 1 self.widget.add_data(self.d) assert len(self.widget.layers) == 1 def test_updated_on_data_update_message(self): self.register() self.widget.add_data(self.d) layer = self.widget._layer_artist_container[self.d][0] layer.update = MagicMock() self.d.style.color = 'green' assert layer.update.call_count == 1 def test_updated_on_subset_update_message(self): self.register() s = self.d.new_subset() self.widget.add_subset(s) layer = self.widget._layer_artist_container[s][0] layer.update = MagicMock() s.style.color = 'green' assert layer.update.call_count == 1 def test_remove_data(self): self.register() self.widget.add_data(self.d) layer = self.widget._layer_artist_container[self.d][0] layer.clear = MagicMock() self.hub.broadcast( message.DataCollectionDeleteMessage(self.dc, data=self.d)) # TODO: the following currently fails but is not critical, so we # skip for now. # assert layer.clear.call_count == 1 assert self.d not in self.widget._layer_artist_container def test_remove_subset(self): self.register() s = self.d.new_subset() self.widget.add_subset(s) layer = self.widget._layer_artist_container[s][0] layer.clear = MagicMock() self.hub.broadcast(message.SubsetDeleteMessage(s)) assert layer.clear.call_count == 1 assert self.d not in self.widget._layer_artist_container def test_subsets_added_with_data(self): s = self.d.new_subset() self.widget.add_data(self.d) assert s in self.widget._layer_artist_container def test_subsets_live_added(self): self.register() self.widget.add_data(self.d) s = self.d.new_subset() assert s in self.widget._layer_artist_container
class Test3DExtractor(object): def setup_method(self, method): self.data = Data() self.data.coords = MockCoordinates() self.data.add_component(np.random.random((3, 4, 5)), label='x') self.x = self.data['x'] def test_abcissa(self): expected = [0, 2, 4] actual = Extractor.abcissa(self.data, 0) np.testing.assert_equal(expected, actual) expected = [0, 2, 4, 6] actual = Extractor.abcissa(self.data, 1) np.testing.assert_equal(expected, actual) expected = [0, 2, 4, 6, 8] actual = Extractor.abcissa(self.data, 2) np.testing.assert_equal(expected, actual) def test_spectrum(self): roi = RectangularROI() roi.update_limits(0, 0, 3, 3) expected = self.x[:, :3, :3].mean(axis=1).mean(axis=1) _, actual = Extractor.spectrum(self.data, self.data.id['x'], roi, (0, 'x', 'y'), 0) np.testing.assert_array_almost_equal(expected, actual) def test_spectrum_oob(self): roi = RectangularROI() roi.update_limits(-1, -1, 3, 3) expected = self.x[:, :3, :3].mean(axis=1).mean(axis=1) _, actual = Extractor.spectrum(self.data, self.data.id['x'], roi, (0, 'x', 'y'), 0) np.testing.assert_array_almost_equal(expected, actual) def test_pixel2world(self): # p2w(x) = 2x, 0 <= x <= 2 assert Extractor.pixel2world(self.data, 0, 1) == 2 # clips to boundary assert Extractor.pixel2world(self.data, 0, -1) == 0 assert Extractor.pixel2world(self.data, 0, 5) == 4 def test_world2pixel(self): # w2p(x) = x/2, 0 <= x <= 4 assert Extractor.world2pixel(self.data, 0, 2.01) == 1 # clips to boundary assert Extractor.world2pixel(self.data, 0, -1) == 0 assert Extractor.world2pixel(self.data, 0, 8) == 2 def test_extract_subset(self): sub = self.data.new_subset() sub.subset_state = self.data.id['x'] > .5 slc = (0, 'y', 'x') mask = sub.to_mask()[0] mask = mask.reshape(-1, mask.shape[0], mask.shape[1]) expected = (self.x * mask).sum(axis=1).sum(axis=1) expected /= mask.sum(axis=1).sum(axis=1) _, actual = Extractor.subset_spectrum(sub, self.data.id['x'], slc, 0) np.testing.assert_array_almost_equal(expected, actual)
class TestProfileViewer(object): def setup_method(self, method): self.data = Data(label='d1') self.data.coords = SimpleCoordinates() self.data['x'] = np.arange(24).reshape((3, 4, 2)) self.data2 = Data(label='d2') self.data2['y'] = np.arange(24).reshape((3, 4, 2)) self.app = GlueApplication() self.session = self.app.session self.hub = self.session.hub self.data_collection = self.session.data_collection self.data_collection.append(self.data) self.data_collection.append(self.data2) self.viewer = self.app.new_data_viewer(ProfileViewer) def teardown_method(self, method): self.viewer.close() self.viewer = None self.app.close() self.app = None def test_functions(self): self.viewer.add_data(self.data) self.viewer.state.function = 'mean' assert len(self.viewer.layers) == 1 layer_artist = self.viewer.layers[0] assert_allclose(layer_artist.state.profile[0], [0, 2, 4]) assert_allclose(layer_artist.state.profile[1], [3.5, 11.5, 19.5]) def test_incompatible(self): self.viewer.add_data(self.data) data2 = Data(y=np.random.random((3, 4, 2))) self.data_collection.append(data2) self.viewer.add_data(data2) assert len(self.viewer.layers) == 2 assert self.viewer.layers[0].enabled assert not self.viewer.layers[1].enabled def test_selection(self): self.viewer.add_data(self.data) self.viewer.state.x_att = self.data.pixel_component_ids[0] roi = XRangeROI(0.9, 2.1) self.viewer.apply_roi(roi) assert len(self.data.subsets) == 1 assert_equal(self.data.subsets[0].to_mask()[:, 0, 0], [0, 1, 1]) self.viewer.state.x_att = self.data.world_component_ids[0] roi = XRangeROI(1.9, 3.1) self.viewer.apply_roi(roi) assert len(self.data.subsets) == 1 assert_equal(self.data.subsets[0].to_mask()[:, 0, 0], [0, 1, 0]) def test_enabled_layers(self): data2 = Data(label='d1', y=np.arange(24).reshape((3, 4, 2)), coords=IdentityCoordinates(n_dim=3)) self.data_collection.append(data2) self.viewer.add_data(self.data) self.viewer.add_data(data2) assert self.viewer.layers[0].enabled assert not self.viewer.layers[1].enabled self.data_collection.add_link( ComponentLink([data2.world_component_ids[1]], self.data.world_component_ids[0], using=lambda x: 2 * x)) assert self.viewer.layers[0].enabled assert self.viewer.layers[1].enabled def test_slice_subset_state(self): self.viewer.add_data(self.data) subset = self.data.new_subset() subset.subset_state = SliceSubsetState( self.data, [slice(1, 2), slice(None)]) assert self.viewer.layers[0].enabled assert self.viewer.layers[1].enabled def test_clone(self): # Regression test for a bug that meant that deserializing a profile # viewer resulted in disabled layers self.viewer.add_data(self.data) subset = self.data.new_subset() subset.subset_state = SliceSubsetState( self.data, [slice(1, 2), slice(None)]) app = clone(self.app) assert app.viewers[0][0].layers[0].enabled assert app.viewers[0][0].layers[1].enabled app.close() def test_incompatible_on_add(self): # Regression test for a bug when adding a dataset to a profile viewer # with a single incompatible subset. subset_state = SliceSubsetState(self.data, [slice(1, 2), slice(None)]) self.data_collection.new_subset_group(subset_state=subset_state, label='s1') data2 = Data(x=[[2, 3], [4, 3]], label='d2') self.data_collection.append(data2) self.viewer.add_data(data2) def test_dependent_axes(self): # Make sure that if we pick a world component that has correlations with # others and is not lined up with the pixel grid, a warning is shown. self.viewer.add_data(self.data) self.viewer.state.x_att = self.data.pixel_component_ids[0] assert self.viewer.options_widget().ui.text_warning.text() == '' self.viewer.state.x_att = self.data.pixel_component_ids[1] assert self.viewer.options_widget().ui.text_warning.text() == '' self.viewer.state.x_att = self.data.pixel_component_ids[2] assert self.viewer.options_widget().ui.text_warning.text() == '' self.viewer.state.x_att = self.data.world_component_ids[0] assert self.viewer.options_widget().ui.text_warning.text() == '' self.viewer.state.x_att = self.data.world_component_ids[1] assert self.viewer.options_widget().ui.text_warning.text() != '' self.viewer.state.x_att = self.data.world_component_ids[2] assert self.viewer.options_widget().ui.text_warning.text() != '' def test_multiple_data(self, tmpdir): # Regression test for issues when multiple datasets are present # and the reference data is not the default one. self.viewer.add_data(self.data) self.viewer.add_data(self.data2) assert self.viewer.layers[0].enabled assert not self.viewer.layers[1].enabled # Make sure that when changing the reference data, which layer # is enabled changes. self.viewer.state.reference_data = self.data2 assert not self.viewer.layers[0].enabled assert self.viewer.layers[1].enabled # Make sure that everything works fine after saving/reloading filename = tmpdir.join('test_multiple_data.glu').strpath self.session.application.save_session(filename) with open(filename, 'r') as f: session = f.read() state = GlueUnSerializer.loads(session) ga = state.object('__main__') viewer = ga.viewers[0][0] assert not viewer.layers[0].enabled assert viewer.layers[1].enabled ga.close() @pytest.mark.parametrize('protocol', [1]) def test_session_back_compat(self, protocol): filename = os.path.join(DATA, 'profile_v{0}.glu'.format(protocol)) with open(filename, 'r') as f: session = f.read() state = GlueUnSerializer.loads(session) ga = state.object('__main__') dc = ga.session.data_collection assert len(dc) == 1 assert dc[0].label == 'array' viewer1 = ga.viewers[0][0] assert len(viewer1.state.layers) == 3 assert viewer1.state.x_att_pixel is dc[0].pixel_component_ids[0] assert_allclose(viewer1.state.x_min, -0.5) assert_allclose(viewer1.state.x_max, 2.5) assert_allclose(viewer1.state.y_min, 13) assert_allclose(viewer1.state.y_max, 63) assert viewer1.state.function == 'maximum' assert not viewer1.state.normalize assert viewer1.state.layers[0].visible assert viewer1.state.layers[1].visible assert viewer1.state.layers[2].visible viewer2 = ga.viewers[0][1] assert viewer2.state.x_att_pixel is dc[0].pixel_component_ids[1] assert_allclose(viewer2.state.x_min, -0.5) assert_allclose(viewer2.state.x_max, 3.5) assert_allclose(viewer2.state.y_min, -0.1) assert_allclose(viewer2.state.y_max, 1.1) assert viewer2.state.function == 'maximum' assert viewer2.state.normalize assert viewer2.state.layers[0].visible assert not viewer2.state.layers[1].visible assert viewer2.state.layers[2].visible viewer3 = ga.viewers[0][2] assert viewer3.state.x_att_pixel is dc[0].pixel_component_ids[2] assert_allclose(viewer3.state.x_min, -0.5) assert_allclose(viewer3.state.x_max, 4.5) assert_allclose(viewer3.state.y_min, -0.4) assert_allclose(viewer3.state.y_max, 4.4) assert viewer3.state.function == 'minimum' assert not viewer3.state.normalize assert viewer3.state.layers[0].visible assert viewer3.state.layers[1].visible assert not viewer3.state.layers[2].visible viewer4 = ga.viewers[0][3] assert viewer4.state.x_att_pixel is dc[0].pixel_component_ids[2] assert_allclose(viewer4.state.x_min, -5.5) assert_allclose(viewer4.state.x_max, 9.5) assert_allclose(viewer4.state.y_min, 27.1) assert_allclose(viewer4.state.y_max, 31.9) assert viewer4.state.function == 'mean' assert not viewer4.state.normalize assert viewer4.state.layers[0].visible assert not viewer4.state.layers[1].visible assert not viewer4.state.layers[2].visible ga.close()
class Test3DExtractor(object): def setup_method(self, method): self.data = Data() self.data.coords = MockCoordinates() self.data.add_component(np.random.random((3, 4, 5)), label='x') self.x = self.data['x'] def test_abcissa(self): expected = [0, 2, 4] actual = Extractor.abcissa(self.data, 0) np.testing.assert_equal(expected, actual) expected = [0, 2, 4, 6] actual = Extractor.abcissa(self.data, 1) np.testing.assert_equal(expected, actual) expected = [0, 2, 4, 6, 8] actual = Extractor.abcissa(self.data, 2) np.testing.assert_equal(expected, actual) def test_spectrum(self): roi = RectangularROI() roi.update_limits(0, 0, 3, 3) expected = self.x[:, :3, :3].mean(axis=1).mean(axis=1) _, actual = Extractor.spectrum( self.data, self.data.id['x'], roi, (0, 'x', 'y'), 0) np.testing.assert_array_almost_equal(expected, actual) def test_spectrum_oob(self): roi = RectangularROI() roi.update_limits(-1, -1, 3, 3) expected = self.x[:, :3, :3].mean(axis=1).mean(axis=1) _, actual = Extractor.spectrum(self.data, self.data.id['x'], roi, (0, 'x', 'y'), 0) np.testing.assert_array_almost_equal(expected, actual) def test_pixel2world(self): # p2w(x) = 2x, 0 <= x <= 2 assert Extractor.pixel2world(self.data, 0, 1) == 2 # clips to boundary assert Extractor.pixel2world(self.data, 0, -1) == 0 assert Extractor.pixel2world(self.data, 0, 5) == 4 def test_world2pixel(self): # w2p(x) = x/2, 0 <= x <= 4 assert Extractor.world2pixel(self.data, 0, 2.01) == 1 # clips to boundary assert Extractor.world2pixel(self.data, 0, -1) == 0 assert Extractor.world2pixel(self.data, 0, 8) == 2 def test_extract_subset(self): sub = self.data.new_subset() sub.subset_state = self.data.id['x'] > .5 slc = (0, 'y', 'x') mask = sub.to_mask()[0] mask = mask.reshape(-1, mask.shape[0], mask.shape[1]) expected = (self.x * mask).sum(axis=1).sum(axis=1) expected /= mask.sum(axis=1).sum(axis=1) _, actual = Extractor.subset_spectrum(sub, self.data.id['x'], slc, 0) np.testing.assert_array_almost_equal(expected, actual)
class TestHistogramLayerArtist(object): def setup_method(self, method): self.viewer_state = HistogramViewerState() ax = plt.subplot(1, 1, 1) self.data = Data(x=[1, 2, 3], y=[2, 3, 4]) self.subset = self.data.new_subset() self.subset.subset_state = self.data.id['x'] > 1 dc = DataCollection([self.data]) # TODO: The following line shouldn't be needed self.viewer_state.data_collection = dc self.artist = HistogramLayerArtist(ax, self.viewer_state, layer=self.subset) self.layer_state = self.artist.state self.viewer_state.layers.append(self.layer_state) self.call_counter = CallCounter() sys.setprofile(self.call_counter) def teardown_method(self, method): sys.setprofile(None) def test_recalc_on_state_changes(self): assert self.call_counter['_calculate_histogram'] == 0 assert self.call_counter['_scale_histogram'] == 0 # attribute self.viewer_state.x_att = self.data.id['y'] assert self.call_counter['_calculate_histogram'] == 1 assert self.call_counter['_scale_histogram'] == 1 # lo self.viewer_state.hist_x_min = -1 assert self.call_counter['_calculate_histogram'] == 2 assert self.call_counter['_scale_histogram'] == 2 # hi self.viewer_state.hist_x_max = 5 assert self.call_counter['_calculate_histogram'] == 3 assert self.call_counter['_scale_histogram'] == 3 # nbins self.viewer_state.hist_n_bin += 1 assert self.call_counter['_calculate_histogram'] == 4 assert self.call_counter['_scale_histogram'] == 4 # xlog self.viewer_state.x_log ^= True assert self.call_counter['_calculate_histogram'] == 5 assert self.call_counter['_scale_histogram'] == 5 # ylog -- no call self.viewer_state.y_log ^= True assert self.call_counter['_calculate_histogram'] == 5 assert self.call_counter['_scale_histogram'] == 6 # cumulative -- no call self.viewer_state.cumulative ^= True assert self.call_counter['_calculate_histogram'] == 5 assert self.call_counter['_scale_histogram'] == 7 # normed -- no call self.viewer_state.normalize ^= True assert self.call_counter['_calculate_histogram'] == 5 assert self.call_counter['_scale_histogram'] == 8 # subset style -- no call self.subset.style.color = '#00ff00' assert self.call_counter['_calculate_histogram'] == 5 assert self.call_counter['_scale_histogram'] == 8
class TestWWTDataViewer(object): def setup_method(self, method): self.d = Data(x=[1, 2, 3], y=[2, 3, 4]) self.dc = DataCollection([self.d]) self.hub = self.dc.hub self.session = Session(data_collection=self.dc, hub=self.hub) self.widget = WWTDataViewer(self.session, webdriver_class=MagicMock) self.options = self.widget.options_widget() def register(self): self.widget.register_to_hub(self.hub) def test_add_data(self): self.widget.add_data(self.d) self.options.ra_att = self.d.id['x'], self.d self.options.dec_att = self.d.id['y'], self.d assert self.d in self.widget def test_double_add_ignored(self): assert len(self.widget) == 0 self.widget.add_data(self.d) assert len(self.widget) == 1 self.widget.add_data(self.d) assert len(self.widget) == 1 def test_updated_on_data_update_message(self): self.register() self.widget.add_data(self.d) layer = self.widget._layer_artist_container[self.d][0] layer.update = MagicMock() self.d.style.color = 'green' assert layer.update.call_count == 1 def test_updated_on_subset_update_message(self): self.register() s = self.d.new_subset() self.widget.add_subset(s) layer = self.widget._layer_artist_container[s][0] layer.update = MagicMock() s.style.color = 'green' assert layer.update.call_count == 1 def test_remove_data(self): self.register() self.widget.add_data(self.d) layer = self.widget._layer_artist_container[self.d][0] layer.clear = MagicMock() self.hub.broadcast( message.DataCollectionDeleteMessage(self.dc, data=self.d)) # TODO: the following currently fails but is not critical, so we # skip for now. # assert layer.clear.call_count == 1 assert self.d not in self.widget def test_remove_subset(self): self.register() s = self.d.new_subset() self.widget.add_subset(s) layer = self.widget._layer_artist_container[s][0] layer.clear = MagicMock() self.hub.broadcast(message.SubsetDeleteMessage(s)) assert layer.clear.call_count == 1 assert self.d not in self.widget def test_subsets_added_with_data(self): s = self.d.new_subset() self.widget.add_data(self.d) assert s in self.widget def test_subsets_live_added(self): self.register() self.widget.add_data(self.d) s = self.d.new_subset() assert s in self.widget # TODO: determine if the following test is the desired behavior # def test_subsets_not_live_added_if_data_not_present(self): # self.register() # s = self.d.new_subset() # assert s not in self.widget def test_updated_on_add(self): self.register() self.widget._update_layer = MagicMock() self.widget.add_data(self.d) # TODO: ideally, the following should be called exactly once assert self.widget._update_layer.call_count >= 1 def test_updated_on_coordinate_change(self): self.register() self.widget.add_data(self.d) self.options.ra_att = self.d.id['x'], self.d self.options.dec_att = self.d.id['y'], self.d artist = self.widget._layer_artist_container[self.d][0] self.widget._update_layer = MagicMock() self.options.ra_att = self.d.id['y'], self.d self.widget._update_layer.call_count > 0
class TestProfileViewer(object): def setup_method(self, method): self.data = Data(label='d1') self.data.coords = SimpleCoordinates() self.data['x'] = np.arange(24).reshape((3, 4, 2)) self.app = GlueApplication() self.session = self.app.session self.hub = self.session.hub self.data_collection = self.session.data_collection self.data_collection.append(self.data) self.viewer = self.app.new_data_viewer(ProfileViewer) def teardown_method(self, method): self.viewer.close() self.viewer = None self.app.close() self.app = None def test_functions(self): self.viewer.add_data(self.data) self.viewer.state.function = 'mean' assert len(self.viewer.layers) == 1 layer_artist = self.viewer.layers[0] assert_allclose(layer_artist.state.profile[0], [0, 2, 4]) assert_allclose(layer_artist.state.profile[1], [3.5, 11.5, 19.5]) def test_incompatible(self): self.viewer.add_data(self.data) data2 = Data(y=np.random.random((3, 4, 2))) self.data_collection.append(data2) self.viewer.add_data(data2) assert len(self.viewer.layers) == 2 assert self.viewer.layers[0].enabled assert not self.viewer.layers[1].enabled def test_selection(self): self.viewer.add_data(self.data) self.viewer.state.x_att = self.data.pixel_component_ids[0] roi = XRangeROI(0.9, 2.1) self.viewer.apply_roi(roi) assert len(self.data.subsets) == 1 assert_equal(self.data.subsets[0].to_mask()[:, 0, 0], [0, 1, 1]) self.viewer.state.x_att = self.data.world_component_ids[0] roi = XRangeROI(1.9, 3.1) self.viewer.apply_roi(roi) assert len(self.data.subsets) == 1 assert_equal(self.data.subsets[0].to_mask()[:, 0, 0], [0, 1, 0]) def test_enabled_layers(self): data2 = Data(label='d1', y=np.arange(24).reshape((3, 4, 2))) self.data_collection.append(data2) self.viewer.add_data(self.data) self.viewer.add_data(data2) assert self.viewer.layers[0].enabled assert not self.viewer.layers[1].enabled self.data_collection.add_link( ComponentLink([data2.world_component_ids[1]], self.data.world_component_ids[0], using=lambda x: 2 * x)) assert self.viewer.layers[0].enabled assert self.viewer.layers[1].enabled def test_slice_subset_state(self): self.viewer.add_data(self.data) subset = self.data.new_subset() subset.subset_state = SliceSubsetState( self.data, [slice(1, 2), slice(None)]) assert self.viewer.layers[0].enabled assert self.viewer.layers[1].enabled def test_clone(self): # Regression test for a bug that meant that deserializing a profile # viewer resulted in disabled layers self.viewer.add_data(self.data) subset = self.data.new_subset() subset.subset_state = SliceSubsetState( self.data, [slice(1, 2), slice(None)]) app = clone(self.app) assert app.viewers[0][0].layers[0].enabled assert app.viewers[0][0].layers[1].enabled app.close() def test_incompatible_on_add(self): # Regression test for a bug when adding a dataset to a profile viewer # with a single incompatible subset. subset_state = SliceSubsetState(self.data, [slice(1, 2), slice(None)]) self.data_collection.new_subset_group(subset_state=subset_state, label='s1') data2 = Data(x=[[2, 3], [4, 3]], label='d2') self.data_collection.append(data2) self.viewer.add_data(data2)