class TestExporter(): def setup_method(self, method): self.exporter = MySubsetMaskExporter() self.exporter.filename = 'test-filename' self.exporter.writer = MagicMock() self.data = Data(x=[1, 2, 3]) self.data_collection = DataCollection([self.data]) def test_no_subsets(self): with pytest.raises(ValueError) as exc: self.exporter.run(self.data) assert exc.value.args[0] == 'Data has no subsets' def test_multiple_valid(self): self.subset1 = self.data_collection.new_subset_group( subset_state=self.data.id['x'] >= 2, label='subset a') self.subset2 = self.data_collection.new_subset_group( subset_state=self.data.id['x'] >= 3, label='subset b') self.exporter.run(self.data) assert self.exporter.writer.call_count == 1 assert self.exporter.writer.call_args[0][0] == 'test-filename' masks = self.exporter.writer.call_args[0][1] assert len(masks) == 2 assert_equal(masks['subset a'], [0, 1, 1]) assert_equal(masks['subset b'], [0, 0, 1]) def test_single_subset_valid(self): self.subset = self.data_collection.new_subset_group( subset_state=self.data.id['x'] >= 2, label='subset a') self.exporter.run(self.data.subsets[0]) assert self.exporter.writer.call_count == 1 assert self.exporter.writer.call_args[0][0] == 'test-filename' masks = self.exporter.writer.call_args[0][1] assert len(masks) == 1 assert_equal(masks['subset a'], [0, 1, 1])
class TestExportPython(BaseTestExportPython): def setup_method(self, method): with NumpyRNGContext(12345): self.data = Data(cube=np.random.random((30, 50, 20))) self.data_collection = DataCollection([self.data]) self.app = GlueApplication(self.data_collection) self.viewer = self.app.new_data_viewer(ImageViewer) self.viewer.add_data(self.data) # FIXME: On some platforms, using an integer label size # causes some of the labels to be non-deterministically # shifted by one pixel, so we pick a non-round font size # to avoid this. self.viewer.state.x_ticklabel_size = 8.21334111 self.viewer.state.y_ticklabel_size = 8.21334111 def teardown_method(self, method): self.viewer.close() self.viewer = None self.app.close() self.app = None def test_simple(self, tmpdir): self.assert_same(tmpdir) def test_simple_att(self, tmpdir): self.viewer.state.x_att = self.data.pixel_component_ids[1] self.viewer.state.y_att = self.data.pixel_component_ids[0] self.assert_same(tmpdir) def test_simple_visual(self, tmpdir): self.viewer.state.layers[0].cmap = plt.cm.RdBu self.viewer.state.layers[0].v_min = 0.2 self.viewer.state.layers[0].v_max = 0.8 self.viewer.state.layers[0].stretch = 'sqrt' self.viewer.state.layers[0].stretch = 'sqrt' self.viewer.state.layers[0].contrast = 0.9 self.viewer.state.layers[0].bias = 0.6 self.assert_same(tmpdir) def test_slice(self, tmpdir): self.viewer.state.x_att = self.data.pixel_component_ids[1] self.viewer.state.y_att = self.data.pixel_component_ids[0] self.viewer.state.slices = (2, 3, 4) self.assert_same(tmpdir) def test_aspect(self, tmpdir): self.viewer.state.aspect = 'auto' self.assert_same(tmpdir) def test_subset(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['cube'] > 0.5) self.assert_same(tmpdir) def test_subset_slice(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['cube'] > 0.5) self.test_slice(tmpdir)
class TestExportPython(BaseTestExportPython): def setup_method(self, method): with NumpyRNGContext(12345): self.data = Data(**dict( (name, random_with_nan(100, nan_index=idx + 1)) for idx, name in enumerate('abcdefgh'))) self.data_collection = DataCollection([self.data]) self.app = GlueApplication(self.data_collection) self.viewer = self.app.new_data_viewer(HistogramViewer) self.viewer.add_data(self.data) self.viewer.state.x_att = self.data.id['a'] def teardown_method(self, method): self.viewer.close() self.viewer = None self.app.close() self.app = None def test_simple(self, tmpdir): self.assert_same(tmpdir) def test_simple_visual(self, tmpdir): self.viewer.state.layers[0].color = 'blue' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_simple_visual_legend(self, tmpdir): self.viewer.state.legend.visible = True self.viewer.state.layers[0].color = 'blue' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_cumulative(self, tmpdir): self.viewer.state.cumulative = True self.assert_same(tmpdir) def test_normalize(self, tmpdir): self.viewer.state.normalize = True self.assert_same(tmpdir) def test_subset(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_subset_legend(self, tmpdir): self.viewer.state.legend.visible = True self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_empty(self, tmpdir): self.viewer.state.x_min = 10 self.viewer.state.x_max = 11 self.viewer.state.hist_x_min = 10 self.viewer.state.hist_x_max = 11 self.assert_same(tmpdir)
class TestExportPython(BaseTestExportPython): def setup_method(self, method): with NumpyRNGContext(12345): self.data = Data(cube=np.random.random((30, 50, 20))) self.data_collection = DataCollection([self.data]) self.app = GlueApplication(self.data_collection) self.viewer = self.app.new_data_viewer(ImageViewer) self.viewer.add_data(self.data) # FIXME: On some platforms, using an integer label size # causes some of the labels to be non-deterministically # shifted by one pixel, so we pick a non-round font size # to avoid this. self.viewer.state.x_ticklabel_size = 8.21334111 self.viewer.state.y_ticklabel_size = 8.21334111 def teardown_method(self, method): self.viewer.close() self.viewer = None self.app.close() self.app = None def test_simple(self, tmpdir): self.assert_same(tmpdir) def test_simple_att(self, tmpdir): self.viewer.state.x_att = self.data.pixel_component_ids[1] self.viewer.state.y_att = self.data.pixel_component_ids[0] self.assert_same(tmpdir) def test_simple_visual(self, tmpdir): self.viewer.state.layers[0].cmap = plt.cm.RdBu self.viewer.state.layers[0].v_min = 0.2 self.viewer.state.layers[0].v_max = 0.8 self.viewer.state.layers[0].stretch = 'sqrt' self.viewer.state.layers[0].stretch = 'sqrt' self.viewer.state.layers[0].contrast = 0.9 self.viewer.state.layers[0].bias = 0.6 self.assert_same(tmpdir) def test_slice(self, tmpdir): self.viewer.state.x_att = self.data.pixel_component_ids[1] self.viewer.state.y_att = self.data.pixel_component_ids[0] self.viewer.state.slices = (2, 3, 4) self.assert_same(tmpdir) def test_aspect(self, tmpdir): self.viewer.state.aspect = 'auto' self.assert_same(tmpdir) def test_subset(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['cube'] > 0.5) self.assert_same(tmpdir) def test_subset_slice(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['cube'] > 0.5) self.test_slice(tmpdir)
def test_translator_from_data_with_derived(): # Case where we convert a subset to a DataFrame data = Data() data['a'] = [3, 5, 6, 7] data['b'] = data.id['a'] + 1 dc = DataCollection([data]) dc.new_subset_group(label='test subset', subset_state=data.id['b'] > 2) df = data.get_object(cls=DataFrame) assert_equal(list(df.columns), ['a', 'b']) assert_equal(df['a'].values, [3, 5, 6, 7]) assert_equal(df['b'].values, [4, 6, 7, 8])
def test_exporter_cancel(tmpdir): filename = tmpdir.join('test.fits').strpath data = Data(x=[1, 2, 3]) data_collection = DataCollection([data]) data_collection.new_subset_group(subset_state=data.id['x'] >= 2, label='subset a') with patch('qtpy.compat.getsavefilename') as o: o.return_value = '', '' # simulates cancelling exporter = QtSubsetMaskExporter() exporter.run(data) assert not os.path.exists(filename)
def test_translator_from_subset(): # Case where we convert a subset to a DataFrame data = Data() data['a'] = [3, 5, 6, 7] data['b'] = [1.5, 2.2, 1.3, 3.3] data['c'] = ['r', 'd', 'w', 'q'] dc = DataCollection([data]) dc.new_subset_group(label='test subset', subset_state=data.id['b'] > 2) df = data.get_subset_object(cls=DataFrame) assert_equal(list(df.columns), ['a', 'b', 'c']) assert_equal(df['a'].values, [5, 7]) assert_equal(df['b'].values, [2.2, 3.3]) assert_equal(df['c'].values, ['d', 'q'])
def test_add_data_with_incompatible_subsets(tmpdir): data1 = Data(label="Data 1", x=np.arange(24).reshape((4, 3, 2))) data2 = Data(label="Data 2", y=np.arange(24).reshape((4, 3, 2))) dc = DataCollection([data1, data2]) ga = GlueApplication(dc) ga.show() # Subset is defined in terms of data2, so it's an incompatible subset # for data1 dc.new_subset_group(subset_state=data2.id['y'] > 0.5, label='subset 1') volume = ga.new_data_viewer(VispyVolumeViewer) volume.add_data(data1) ga.close()
class TestExportPython(BaseTestExportPython): def setup_method(self, method): with NumpyRNGContext(12345): self.data = Data(**dict((name, random_with_nan(100, nan_index=idx + 1)) for idx, name in enumerate('abcdefgh'))) self.data_collection = DataCollection([self.data]) self.app = GlueApplication(self.data_collection) self.viewer = self.app.new_data_viewer(HistogramViewer) self.viewer.add_data(self.data) self.viewer.state.x_att = self.data.id['a'] def teardown_method(self, method): self.viewer.close() self.viewer = None self.app.close() self.app = None def test_simple(self, tmpdir): self.assert_same(tmpdir) def test_simple_visual(self, tmpdir): self.viewer.state.layers[0].color = 'blue' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_cumulative(self, tmpdir): self.viewer.state.cumulative = True self.assert_same(tmpdir) def test_normalize(self, tmpdir): self.viewer.state.normalize = True self.assert_same(tmpdir) def test_subset(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_empty(self, tmpdir): self.viewer.state.x_min = 10 self.viewer.state.x_max = 11 self.viewer.state.hist_x_min = 10 self.viewer.state.hist_x_max = 11 self.assert_same(tmpdir)
def test_add_subset(): # Regression test for a bug that occurred when adding a subset # directly to the table viewer. data1 = Data(a=[1, 2, 3, 4, 5], label='test1') data2 = Data(a=[1, 2, 3, 4, 5], label='test2') dc = DataCollection([data1, data2]) dc.new_subset_group('test subset 1', data1.id['a'] > 2) gapp = GlueApplication(dc) viewer = gapp.new_data_viewer(TableViewer) viewer.add_subset(data1.subsets[0]) assert len(viewer.state.layers) == 2 assert not viewer.state.layers[0].visible assert viewer.state.layers[1].visible dc.new_subset_group('test subset 2', data1.id['a'] <= 2) assert len(viewer.state.layers) == 3 assert not viewer.state.layers[0].visible assert viewer.state.layers[1].visible assert viewer.state.layers[2].visible viewer.remove_subset(data1.subsets[1]) assert len(viewer.state.layers) == 2 assert not viewer.state.layers[0].visible assert viewer.state.layers[1].visible viewer.add_subset(data1.subsets[1]) assert len(viewer.state.layers) == 3 assert not viewer.state.layers[0].visible assert viewer.state.layers[1].visible assert viewer.state.layers[2].visible with pytest.raises(ValueError) as exc: viewer.add_subset(data2.subsets[1]) assert exc.value.args[ 0] == 'subset parent data does not match existing table data'
def test_exporter(tmpdir): filename = tmpdir.join('test.fits').strpath data = Data(x=[1, 2, 3]) data_collection = DataCollection([data]) data_collection.new_subset_group(subset_state=data.id['x'] >= 2, label='subset a') with patch('qtpy.compat.getsavefilename') as o: o.return_value = filename, 'FITS (*.fits *.fit *.fits.gz *.fit.gz)' exporter = QtSubsetMaskExporter() exporter.run(data) with fits.open(filename) as hdulist: assert len(hdulist) == 2 assert hdulist[0].data is None assert hdulist[1].name == 'SUBSET A' assert_equal(hdulist[1].data, [0, 1, 1])
class TestExportPython(BaseTestExportPython): def setup_method(self, method): with NumpyRNGContext(12345): self.data = Data(cube=np.random.random((30, 50, 20))) self.data_collection = DataCollection([self.data]) ga = GlueApplication(self.data_collection) self.viewer = ga.new_data_viewer(ImageViewer) self.viewer.add_data(self.data) def test_simple(self, tmpdir): self.assert_same(tmpdir) def test_simple_visual(self, tmpdir): self.viewer.state.layers[0].cmap = plt.cm.RdBu self.viewer.state.layers[0].v_min = 0.2 self.viewer.state.layers[0].v_max = 0.8 self.viewer.state.layers[0].stretch = 'sqrt' self.viewer.state.layers[0].stretch = 'sqrt' self.viewer.state.layers[0].contrast = 0.9 self.viewer.state.layers[0].bias = 0.6 self.assert_same(tmpdir) def test_slice(self, tmpdir): self.viewer.state.x_att = self.data.pixel_component_ids[1] self.viewer.state.y_att = self.data.pixel_component_ids[0] self.viewer.state.slices = (2, 3, 4) self.assert_same(tmpdir) def test_aspect(self, tmpdir): self.viewer.state.aspect = 'auto' self.assert_same(tmpdir) def test_subset(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['cube'] > 0.5) self.assert_same(tmpdir) def test_subset_slice(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['cube'] > 0.5) self.test_slice(tmpdir)
def test_add_data_with_incompatible_subsets(tmpdir): # Regression test for a bug that an error when adding a dataset with an # incompatible subset to a 3D scatter viewer. data1 = Data(label="Data 1", x=[1, 2, 3]) data2 = Data(label="Data 2", y=[4, 5, 6]) dc = DataCollection([data1, data2]) ga = GlueApplication(dc) ga.show() # Subset is defined in terms of data2, so it's an incompatible subset # for data1 dc.new_subset_group(subset_state=data2.id['y'] > 0.5, label='subset 1') scatter = ga.new_data_viewer(VispyScatterViewer) scatter.add_data(data1) ga.close()
def test_scatter_remove_layer_artists(tmpdir): # Regression test for a bug that caused layer states to not be removed # when the matching layer artist was removed. This then caused issues when # loading session files. # Create fake data data = make_test_data() # Create fake session dc = DataCollection([data]) ga = GlueApplication(dc) ga.show() scatter = ga.new_data_viewer(VispyScatterViewer) scatter.add_data(data) dc.new_subset_group(subset_state=data.id['x'] > 0.5, label='subset 1') scatter.add_subset(data.subsets[0]) assert len(scatter.layers) == 2 assert len(scatter.state.layers) == 2 dc.remove_subset_group(dc.subset_groups[0]) assert len(scatter.layers) == 1 assert len(scatter.state.layers) == 1 # Check that writing a session works as expected. session_file = tmpdir.join('test_scatter_viewer.glu').strpath ga.save_session(session_file) ga.close() # Now we can check that everything is restored correctly ga2 = GlueApplication.restore_session(session_file) ga2.show() ga2.close()
def test_table_with_dask_column(): da = pytest.importorskip('dask.array') app = get_qapp() d = Data(d=da.asarray([1, 2, 3, 4, 5]), e=np.arange(5) + 1) dc = DataCollection([d]) gapp = GlueApplication(dc) widget = gapp.new_data_viewer(TableViewer) widget.add_data(d) sg1 = dc.new_subset_group('D <= 3', d.id['d'] <= 3) sg1.style.color = '#aa0000' sg2 = dc.new_subset_group('1 < E < 4', (d.id['e'] > 1) & (d.id['e'] < 4)) sg2.style.color = '#0000cc' assert widget.state.layers[0].visible assert widget.state.layers[1].visible assert widget.state.layers[2].visible model = widget.ui.table.model() # We now check what the data and colors of the table are, and try various # sorting methods to make sure that things are still correct. data = {'d': [1, 2, 3, 4, 5], 'e': [1, 2, 3, 4, 5]} colors = ['#aa0000', '#380088', '#380088', None, None] check_values_and_color(model, data, colors) widget.state.layers[2].visible = False colors = ['#aa0000', '#aa0000', '#aa0000', None, None] check_values_and_color(model, data, colors)
def test_scatter_remove_layer_artists(tmpdir): # Regression test for a bug that caused layer states to not be removed # when the matching layer artist was removed. This then caused issues when # loading session files. # Create fake data data = make_test_data() # Create fake session dc = DataCollection([data]) ga = GlueApplication(dc) ga.show() scatter = ga.new_data_viewer(VispyScatterViewer) scatter.add_data(data) dc.new_subset_group(subset_state=data.id['x'] > 0.5, label='subset 1') scatter.add_subset(data.subsets[0]) assert len(scatter.layers) == 2 assert len(scatter.state.layers) == 2 dc.remove_subset_group(dc.subset_groups[0]) assert len(scatter.layers) == 1 assert len(scatter.state.layers) == 1 # Check that writing a session works as expected. session_file = tmpdir.join('test_scatter_viewer.glu').strpath ga.save_session(session_file) ga.close() # Now we can check that everything is restored correctly ga2 = GlueApplication.restore_session(session_file) ga2.show()
def test_remove_subset_group(): # Regression test for a bug that meant that removing a subset caused an # error when multiple viewers were present. # Create fake data data = make_test_data() # Create fake session dc = DataCollection([data]) ga = GlueApplication(dc) ga.show() volume1 = ga.new_data_viewer(VispyVolumeViewer) volume1.add_data(data) volume2 = ga.new_data_viewer(VispyVolumeViewer) volume2.add_data(data) dc.new_subset_group(subset_state=data.id['a'] > 0, label='Subset 1') dc.remove_subset_group(dc.subset_groups[0]) ga.close()
def test_incompatible_subset(): # Regression test for a bug that caused the table to be refreshed in an # infinite loop if incompatible subsets were present. data1 = Data(a=[1, 2, 3, 4, 5], label='test1') data2 = Data(a=[1, 2, 3, 4, 5], label='test2') dc = DataCollection([data1, data2]) gapp = GlueApplication(dc) viewer = gapp.new_data_viewer(TableViewer) viewer.add_data(data1) dc.new_subset_group('test subset', data2.id['a'] > 2) gapp.show() process_events(0.5) with patch.object(viewer.layers[0], '_refresh') as refresh1: with patch.object(viewer.layers[1], '_refresh') as refresh2: process_events(0.5) assert refresh1.call_count == 0 assert refresh2.call_count == 0
class TestExporter(): def setup_method(self, method): self.exporter = MySubsetMaskExporter() self.exporter.filename = 'test-filename' self.exporter.writer = MagicMock() self.data = Data(x=[1, 2, 3]) self.data_collection = DataCollection([self.data]) def test_no_subsets(self): with pytest.raises(ValueError) as exc: self.exporter.run(self.data) assert exc.value.args[0] == 'Data has no subsets' def test_multiple_valid(self): self.subset1 = self.data_collection.new_subset_group(subset_state=self.data.id['x'] >= 2, label='subset a') self.subset2 = self.data_collection.new_subset_group(subset_state=self.data.id['x'] >= 3, label='subset b') self.exporter.run(self.data) assert self.exporter.writer.call_count == 1 assert self.exporter.writer.call_args[0][0] == 'test-filename' masks = self.exporter.writer.call_args[0][1] assert len(masks) == 2 assert_equal(masks['subset a'], [0, 1, 1]) assert_equal(masks['subset b'], [0, 0, 1]) def test_single_subset_valid(self): self.subset = self.data_collection.new_subset_group(subset_state=self.data.id['x'] >= 2, label='subset a') self.exporter.run(self.data.subsets[0]) assert self.exporter.writer.call_count == 1 assert self.exporter.writer.call_args[0][0] == 'test-filename' masks = self.exporter.writer.call_args[0][1] assert len(masks) == 1 assert_equal(masks['subset a'], [0, 1, 1])
class TestAstropyRegions: def setup_method(self, method): self.data = Data(flux=np.ones((128, 128))) self.dc = DataCollection([self.data]) def test_rectangular_roi(self): subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(1, 3.5, -0.2, 3.3)) self.dc.new_subset_group(subset_state=subset_state, label='rectangular') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 2.25) assert_allclose(reg.center.y, 1.55) assert_allclose(reg.width, 2.5) assert_allclose(reg.height, 3.5) def test_subset_id(self): subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(1, 3.5, -0.2, 3.3)) self.dc.new_subset_group(subset_state=subset_state, label='rectangular') for subset_id in [None, 0, 'rectangular']: reg = self.data.get_selection_definition(format='astropy-regions', subset_id=subset_id) assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 2.25) assert_allclose(reg.center.y, 1.55) assert_allclose(reg.width, 2.5) assert_allclose(reg.height, 3.5) with pytest.raises(ValueError) as exc: self.data.get_selection_definition(format='astropy-regions', subset_id='circular') assert exc.value.args[0] == "No subset found with the label 'circular'" def test_unsupported(self): self.dc.new_subset_group(subset_state=self.data.id['flux'] > 0.5, label='Flux-based selection') with pytest.raises(NotImplementedError) as exc: self.data.get_selection_definition( format='astropy-regions', subset_id='Flux-based selection') assert exc.value.args[ 0] == 'Subset states of type InequalitySubsetState are not supported'
class TestExportPython(BaseTestExportPython): def setup_method(self, method): with NumpyRNGContext(12345): self.data = Data(**dict( (name, random_with_nan(100, nan_index=idx + 1)) for idx, name in enumerate('abcdefgh'))) self.data['angle'] = np.random.uniform(0, 360, 100) self.data_collection = DataCollection([self.data]) self.app = GlueApplication(self.data_collection) self.viewer = self.app.new_data_viewer(ScatterViewer) self.viewer.add_data(self.data) self.viewer.state.x_att = self.data.id['a'] self.viewer.state.y_att = self.data.id['b'] def teardown_method(self, method): self.viewer.close() self.viewer = None self.app.close() self.app = None def test_simple(self, tmpdir): self.assert_same(tmpdir) def test_simple_nofill(self, tmpdir): self.viewer.state.layers[0].fill = False self.viewer.state.layers[0].size_scaling = 10 self.assert_same(tmpdir) def test_simple_visual(self, tmpdir): self.viewer.state.layers[0].color = 'blue' self.viewer.state.layers[0].markersize = 30 self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_cmap_mode(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_att = self.data.id['c'] self.viewer.state.layers[0].cmap = plt.cm.BuGn self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].alpha = 0.8 self.assert_same(tmpdir) def test_cmap_mode_nofill(self, tmpdir): self.viewer.state.layers[0].fill = False self.test_cmap_mode(tmpdir) def test_size_mode(self, tmpdir): self.viewer.state.layers[0].size_mode = 'Linear' self.viewer.state.layers[0].size_att = self.data.id['d'] self.viewer.state.layers[0].size_vmin = 0.1 self.viewer.state.layers[0].size_vmax = 0.8 self.viewer.state.layers[0].size_scaling = 0.4 self.viewer.state.layers[0].alpha = 0.7 self.assert_same(tmpdir) def test_size_mode_nofill(self, tmpdir): self.viewer.state.layers[0].fill = False self.test_size_mode(tmpdir) def test_line(self, tmpdir): self.viewer.state.layers[0].line_visible = True self.viewer.state.layers[0].linewidth = 10 self.viewer.state.layers[0].linestype = 'dashed' self.viewer.state.layers[0].color = 'orange' self.viewer.state.layers[0].alpha = 0.7 self.viewer.state.layers[0].markersize = 100 self.assert_same(tmpdir, tol=5) def test_line_cmap(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.test_line(tmpdir) def test_errorbarx(self, tmpdir): self.viewer.state.layers[0].xerr_visible = True self.viewer.state.layers[0].xerr_att = self.data.id['e'] self.viewer.state.layers[0].color = 'purple' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_errorbary(self, tmpdir): self.viewer.state.layers[0].yerr_visible = True self.viewer.state.layers[0].yerr_att = self.data.id['f'] self.viewer.state.layers[0].color = 'purple' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_errorbarxy(self, tmpdir): self.viewer.state.layers[0].xerr_visible = True self.viewer.state.layers[0].xerr_att = self.data.id['e'] self.viewer.state.layers[0].yerr_visible = True self.viewer.state.layers[0].yerr_att = self.data.id['f'] self.viewer.state.layers[0].color = 'purple' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_errorbarxy_cmap(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.test_errorbarxy(tmpdir) def _vector_common(self, tmpdir): self.viewer.state.layers[0].vector_visible = True self.viewer.state.layers[0].vy_att = self.data.id['g'] self.viewer.state.layers[0].vector_arrowhead = True self.viewer.state.layers[0].vector_origin = 'tail' self.viewer.state.layers[0].vector_scaling = 1.5 self.viewer.state.layers[0].color = 'teal' self.viewer.state.layers[0].alpha = 0.9 self.assert_same(tmpdir, tol=1) def test_vector_cartesian(self, tmpdir): self.viewer.state.layers[0].vector_mode = 'Cartesian' self.viewer.state.layers[0].vx_att = self.data.id['h'] self._vector_common(tmpdir) def test_vector_polar(self, tmpdir): self.viewer.state.layers[0].vector_mode = 'Polar' self.viewer.state.layers[0].vx_att = self.data.id['angle'] self._vector_common(tmpdir) def test_vector_cartesian_cmap(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.test_vector_cartesian(tmpdir) def test_vector_cartesian_xflip(self, tmpdir): # Regression test for a bug that caused vectors to not be flipped self.viewer.state.layers[0].vector_mode = 'Cartesian' self.viewer.state.layers[0].vx_att = self.data.id['h'] self.viewer.state.flip_x() self._vector_common(tmpdir) def test_subset(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_density_map_with_subset(self, tmpdir): self.viewer.state.dpi = 2 self.viewer.state.layers[0].density_map = True self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_density_map_cmap_with_subset(self, tmpdir): self.viewer.state.dpi = 2 self.viewer.state.layers[0].density_map = True self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_cmap_mode_change(self, tmpdir): # Regression test for a bug that caused scatter markers to not change # color when going from Linear to Fixed mode self.viewer.state.layers[0].size_mode = 'Linear' self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_mode = 'Fixed' self.assert_same(tmpdir) def test_density_map_change(self, tmpdir): # Regression test for a bug that caused the density map to still # be visible if using color-coding with the density map then # switching to markers. self.viewer.state.layers[0].density_map = True self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap = plt.cm.BuGn self.viewer.state.layers[0].density_map = False self.assert_same(tmpdir)
def get_subsets_from_viewer(self, viewer_reference, data_label=None): """ Returns the subsets of a specified viewer converted to astropy regions objects. It should be noted that the subset translation machinery lives in the glue-astronomy repository. Currently, the machinery only works on 2D data for cases like range selection. For e.g. a profile viewer that is ostensibly just a view into a 3D data set, it is necessary to first reduce the dimensions of the data, then retrieve the subset information as a regions object. This means that the returned y extents in the region are not strictly representative of the subset range in y. Parameters ---------- viewer_reference : str The reference to the viewer defined with the ``reference`` key in the yaml configuration file. data_label : str, optional Optionally provide a label to retrieve a specific data set from the viewer instance. Returns ------- data : dict A dict of the transformed Glue subset objects, with keys representing the subset name and values as astropy regions objects. """ viewer = self.get_viewer(viewer_reference) data = self.get_data_from_viewer(viewer_reference, data_label, cls=None) regions = {} for key, value in data.items(): if isinstance(value, Subset): # Range selection on a profile is currently not supported in # the glue translation machinery for astropy regions, so we # have to do it manually. Only data that is 2d is supported, # therefore, if the data is already 2d, simply use as is. if value.data.ndim == 2: region = value.data.get_selection_definition( format='astropy-regions') regions[key] = region continue # There is a special case for 1d data (which is also not # supported currently). We now eschew the use of the # translation machinery entirely and construct the astropy # region ourselves. elif value.data.ndim == 1: # Grab the data units from the glue-astronomy spectral axis # TODO: this needs to be much simpler; i.e. data units in # the glue component objects unit = value.data.coords.spectral_axis.unit hi, lo = value.subset_state.hi, value.subset_state.lo xcen = 0.5 * (lo + hi) width = hi - lo region = RectanglePixelRegion( PixCoord(xcen, 0), width, 0, meta={'spectal_axis_unit': unit}) regions[key] = region continue # Get the pixel coordinate [z] of the 3D data, repeating the # wavelength axis. This doesn't seem strictly necessary as it # returns the same data if the pixel axis is [y] or [x] xid = value.data.pixel_component_ids[0] # Construct a new data object collapsing over one of the # spatial dimensions. This is necessary because the astropy # region translation machinery in glue-astronomy does not # support non-2D data, even for range objects. stat_func = 'median' if hasattr(viewer.state, 'function'): stat_func = viewer.state.function # Compute reduced data based on the current viewer's statistic # function. This doesn't seem particularly useful, but better # to be consistent. reduced_data = Data(x=value.data.compute_statistic( stat_func, value.data.id[xid], subset_state=value.subset_state, axis=1)) # Instantiate a new data collection since we need to compose # the collapsed data with the current subset state. We use a # new data collection so as not to inference with the one used # by the application. temp_data_collection = DataCollection() temp_data_collection.append(reduced_data) # Get the data id of the pixel axis that will be used in the # range composition. This is the wavelength axis for the new # 2d data. xid = reduced_data.pixel_component_ids[1] # Create a new subset group to hold our current subset state subset_group = temp_data_collection.new_subset_group( label=value.label, subset_state=value.subset_state) # Set the subset state axis to the wavelength pixel coordinate subset_group.subsets[0].subset_state.att = xid # Use the associated collapsed subset data to get an astropy # regions object dependent on the extends of the subset. # **Note** that the y values in this region object are not # useful, only the x values are. region = subset_group.subsets[0].data.get_selection_definition( format='astropy-regions') regions[key] = region return regions
class TestExportPython(BaseTestExportPython): def setup_method(self, method): self.data = Data(label='d1') self.data.coords = SimpleCoordinates() with NumpyRNGContext(12345): self.data['x'] = random_with_nan(48, 5).reshape((6, 4, 2)) self.data['y'] = random_with_nan(48, 12).reshape((6, 4, 2)) self.data_collection = DataCollection([self.data]) self.app = GlueApplication(self.data_collection) self.viewer = self.app.new_data_viewer(ProfileViewer) self.viewer.add_data(self.data) def teardown_method(self, method): self.viewer.close() self.viewer = None self.app.close() self.app = None def test_simple(self, tmpdir): self.assert_same(tmpdir) def test_color(self, tmpdir): self.viewer.state.layers[0].color = '#ac0567' self.assert_same(tmpdir) def test_linewidth(self, tmpdir): self.viewer.state.layers[0].linewidth = 7.25 self.assert_same(tmpdir) def test_max(self, tmpdir): self.viewer.state.function = 'maximum' self.assert_same(tmpdir) def test_min(self, tmpdir): self.viewer.state.function = 'minimum' self.assert_same(tmpdir) def test_mean(self, tmpdir): self.viewer.state.function = 'mean' self.assert_same(tmpdir) def test_median(self, tmpdir): self.viewer.state.function = 'median' self.assert_same(tmpdir) def test_sum(self, tmpdir): self.viewer.state.function = 'sum' self.assert_same(tmpdir) def test_normalization(self, tmpdir): self.viewer.state.normalize = True self.assert_same(tmpdir) def test_subset(self, tmpdir): self.viewer.state.function = 'mean' self.data_collection.new_subset_group('mysubset', self.data.id['x'] > 0.25) self.assert_same(tmpdir) def test_xatt(self, tmpdir): self.viewer.x_att = self.data.pixel_component_ids[1] self.assert_same(tmpdir) def test_profile_att(self, tmpdir): self.viewer.layers[0].state.attribute = self.data.id['y'] self.assert_same(tmpdir)
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
def test_table_widget(tmpdir): # Start off by creating a glue application instance with a table viewer and # some data pre-loaded. app = get_qapp() d = Data(a=[1, 2, 3, 4, 5], b=[3.2, 1.2, 4.5, 3.3, 2.2], c=['e', 'b', 'c', 'a', 'f']) dc = DataCollection([d]) gapp = GlueApplication(dc) widget = gapp.new_data_viewer(TableViewer) widget.add_data(d) subset_mode = gapp._session.edit_subset_mode # Create two subsets sg1 = dc.new_subset_group('D <= 3', d.id['a'] <= 3) sg1.style.color = '#aa0000' sg2 = dc.new_subset_group('1 < D < 4', (d.id['a'] > 1) & (d.id['a'] < 4)) sg2.style.color = '#0000cc' model = widget.ui.table.model() # We now check what the data and colors of the table are, and try various # sorting methods to make sure that things are still correct. data = {'a': [1, 2, 3, 4, 5], 'b': [3.2, 1.2, 4.5, 3.3, 2.2], 'c': ['e', 'b', 'c', 'a', 'f']} colors = ['#aa0000', '#380088', '#380088', None, None] check_values_and_color(model, data, colors) model.sort(1, Qt.AscendingOrder) data = {'a': [2, 5, 1, 4, 3], 'b': [1.2, 2.2, 3.2, 3.3, 4.5], 'c': ['b', 'f', 'e', 'a', 'c']} colors = ['#380088', None, '#aa0000', None, '#380088'] check_values_and_color(model, data, colors) model.sort(2, Qt.AscendingOrder) data = {'a': [4, 2, 3, 1, 5], 'b': [3.3, 1.2, 4.5, 3.2, 2.2], 'c': ['a', 'b', 'c', 'e', 'f']} colors = [None, '#380088', '#380088', '#aa0000', None] check_values_and_color(model, data, colors) model.sort(0, Qt.DescendingOrder) data = {'a': [5, 4, 3, 2, 1], 'b': [2.2, 3.3, 4.5, 1.2, 3.2], 'c': ['f', 'a', 'c', 'b', 'e']} colors = [None, None, '#380088', '#380088', '#aa0000'] check_values_and_color(model, data, colors) model.sort(0, Qt.AscendingOrder) # We now modify the subsets using the table. selection = widget.ui.table.selectionModel() widget.toolbar.actions['table:rowselect'].toggle() def press_key(key): event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, key, Qt.NoModifier) app.postEvent(widget.ui.table, event) app.processEvents() process_events() # We now use key presses to navigate down to the third row press_key(Qt.Key_Tab) press_key(Qt.Key_Down) press_key(Qt.Key_Down) process_events() indices = selection.selectedRows() # We make sure that the third row is selected assert len(indices) == 1 assert indices[0].row() == 2 # At this point, the subsets haven't changed yet np.testing.assert_equal(d.subsets[0].to_mask(), [1, 1, 1, 0, 0]) np.testing.assert_equal(d.subsets[1].to_mask(), [0, 1, 1, 0, 0]) # We specify that we are editing the second subset, and use a 'not' logical # operation to remove the currently selected line from the second subset. subset_mode.edit_subset = [d.subsets[1]] subset_mode.mode = AndNotMode press_key(Qt.Key_Enter) np.testing.assert_equal(d.subsets[0].to_mask(), [1, 1, 1, 0, 0]) np.testing.assert_equal(d.subsets[1].to_mask(), [0, 1, 0, 0, 0]) # At this point, the selection should be cleared indices = selection.selectedRows() assert len(indices) == 0 # We move to the fourth row and now do an 'or' selection with the first # subset. press_key(Qt.Key_Down) subset_mode.mode = OrMode subset_mode.edit_subset = [d.subsets[0]] press_key(Qt.Key_Enter) np.testing.assert_equal(d.subsets[0].to_mask(), [1, 1, 1, 1, 0]) np.testing.assert_equal(d.subsets[1].to_mask(), [0, 1, 0, 0, 0]) # Finally we move to the fifth row and deselect all subsets so that # pressing enter now creates a new subset. press_key(Qt.Key_Down) subset_mode.mode = ReplaceMode subset_mode.edit_subset = None press_key(Qt.Key_Enter) np.testing.assert_equal(d.subsets[0].to_mask(), [1, 1, 1, 1, 0]) np.testing.assert_equal(d.subsets[1].to_mask(), [0, 1, 0, 0, 0]) np.testing.assert_equal(d.subsets[2].to_mask(), [0, 0, 0, 0, 1]) # Make the color for the new subset deterministic dc.subset_groups[2].style.color = '#bababa' # Now finally check saving and restoring session session_file = tmpdir.join('table.glu').strpath gapp.save_session(session_file) gapp2 = GlueApplication.restore_session(session_file) gapp2.show() d = gapp2.data_collection[0] widget2 = gapp2.viewers[0][0] model2 = widget2.ui.table.model() data = {'a': [1, 2, 3, 4, 5], 'b': [3.2, 1.2, 4.5, 3.3, 2.2], 'c': ['e', 'b', 'c', 'a', 'f']} # Need to take into account new selections above colors = ['#aa0000', '#380088', '#aa0000', "#aa0000", "#bababa"] check_values_and_color(model2, data, colors)
interpolation='nearest') pv_viewer = app.add_widget(pvwidget, label="Orbit PV Slice") ax2 = pvwidget.axes dl = (table['l'][1:] - table['l'][:-1]) db = (table['b'][1:] - table['b'][:-1]) dist = (dl**2 + db**2)**0.5 cdist = np.zeros(dist.size + 1) * u.deg cdist[1:] = dist.cumsum() * u.deg #pixscale = ((x[1]-x[0])**2+(y[1]-y[0])**2)**0.5 pixscale = wcs.utils.celestial_pixel_scale(cube.data.coords.wcs) spwcs = cube.data.coords.wcs.sub([wcs.WCSSUB_SPECTRAL]) spax = spwcs.wcs_world2pix(table["v'los"] * 1e3, 0)[0] ax2.plot(cdist / pixscale, spax, 'r-', linewidth=2, alpha=0.5) ax2.set_axis_bgcolor('black') # SERIOUSLY, DO IT ax.axis([x.min(), x.max(), y.min(), y.max()]) dc.new_subset_group(label='T < 60', subset_state=subset_tem_lt_60) dc.new_subset_group(label='T > 60', subset_state=subset_tem_gt_60) dc.subset_groups[0].style.markersize = 15 dc.subset_groups[0].style.marker = '+' dc.subset_groups[0].style.color = 'blue' dc.subset_groups[1].style.markersize = 15 dc.subset_groups[1].style.marker = '*' dc.subset_groups[1].style.color = 'orange' app.start()
class TestExportPython(BaseTestExportPython): def setup_method(self, method): with NumpyRNGContext(12345): self.data = Data(**dict((name, random_with_nan(100, nan_index=idx + 1)) for idx, name in enumerate('abcdefgh'))) self.data['angle'] = np.random.uniform(0, 360, 100) self.data_collection = DataCollection([self.data]) self.app = GlueApplication(self.data_collection) self.viewer = self.app.new_data_viewer(ScatterViewer) self.viewer.add_data(self.data) self.viewer.state.x_att = self.data.id['a'] self.viewer.state.y_att = self.data.id['b'] def teardown_method(self, method): self.viewer.close() self.viewer = None self.app.close() self.app = None def test_simple(self, tmpdir): self.assert_same(tmpdir) def test_simple_nofill(self, tmpdir): self.viewer.state.layers[0].fill = False self.viewer.state.layers[0].size_scaling = 10 self.assert_same(tmpdir) def test_simple_visual(self, tmpdir): self.viewer.state.layers[0].color = 'blue' self.viewer.state.layers[0].markersize = 30 self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_cmap_mode(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_att = self.data.id['c'] self.viewer.state.layers[0].cmap = plt.cm.BuGn self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].alpha = 0.8 self.assert_same(tmpdir) def test_cmap_mode_nofill(self, tmpdir): self.viewer.state.layers[0].fill = False self.test_cmap_mode(tmpdir) def test_size_mode(self, tmpdir): self.viewer.state.layers[0].size_mode = 'Linear' self.viewer.state.layers[0].size_att = self.data.id['d'] self.viewer.state.layers[0].size_vmin = 0.1 self.viewer.state.layers[0].size_vmax = 0.8 self.viewer.state.layers[0].size_scaling = 0.4 self.viewer.state.layers[0].alpha = 0.7 self.assert_same(tmpdir) def test_size_mode_nofill(self, tmpdir): self.viewer.state.layers[0].fill = False self.test_size_mode(tmpdir) def test_line(self, tmpdir): self.viewer.state.layers[0].line_visible = True self.viewer.state.layers[0].linewidth = 10 self.viewer.state.layers[0].linestype = 'dashed' self.viewer.state.layers[0].color = 'orange' self.viewer.state.layers[0].alpha = 0.7 self.viewer.state.layers[0].markersize = 100 self.assert_same(tmpdir, tol=5) def test_line_cmap(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.test_line(tmpdir) def test_errorbarx(self, tmpdir): self.viewer.state.layers[0].xerr_visible = True self.viewer.state.layers[0].xerr_att = self.data.id['e'] self.viewer.state.layers[0].color = 'purple' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_errorbary(self, tmpdir): self.viewer.state.layers[0].yerr_visible = True self.viewer.state.layers[0].yerr_att = self.data.id['f'] self.viewer.state.layers[0].color = 'purple' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_errorbarxy(self, tmpdir): self.viewer.state.layers[0].xerr_visible = True self.viewer.state.layers[0].xerr_att = self.data.id['e'] self.viewer.state.layers[0].yerr_visible = True self.viewer.state.layers[0].yerr_att = self.data.id['f'] self.viewer.state.layers[0].color = 'purple' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_errorbarxy_cmap(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.test_errorbarxy(tmpdir) def _vector_common(self, tmpdir): self.viewer.state.layers[0].vector_visible = True self.viewer.state.layers[0].vy_att = self.data.id['g'] self.viewer.state.layers[0].vector_arrowhead = True self.viewer.state.layers[0].vector_origin = 'tail' self.viewer.state.layers[0].vector_scaling = 1.5 self.viewer.state.layers[0].color = 'teal' self.viewer.state.layers[0].alpha = 0.9 self.assert_same(tmpdir) def test_vector_cartesian(self, tmpdir): self.viewer.state.layers[0].vector_mode = 'Cartesian' self.viewer.state.layers[0].vx_att = self.data.id['h'] self._vector_common(tmpdir) def test_vector_polar(self, tmpdir): self.viewer.state.layers[0].vector_mode = 'Polar' self.viewer.state.layers[0].vx_att = self.data.id['angle'] self._vector_common(tmpdir) def test_vector_cartesian_cmap(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.test_vector_cartesian(tmpdir) def test_vector_cartesian_xflip(self, tmpdir): # Regression test for a bug that caused vectors to not be flipped self.viewer.state.layers[0].vector_mode = 'Cartesian' self.viewer.state.layers[0].vx_att = self.data.id['h'] self.viewer.state.flip_x() self._vector_common(tmpdir) def test_subset(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_density_map_with_subset(self, tmpdir): self.viewer.state.dpi = 2 self.viewer.state.layers[0].density_map = True self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_density_map_cmap_with_subset(self, tmpdir): self.viewer.state.dpi = 2 self.viewer.state.layers[0].density_map = True self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_cmap_mode_change(self, tmpdir): # Regression test for a bug that caused scatter markers to not change # color when going from Linear to Fixed mode self.viewer.state.layers[0].size_mode = 'Linear' self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_mode = 'Fixed' self.assert_same(tmpdir)
def test_table_widget(tmpdir): # Start off by creating a glue application instance with a table viewer and # some data pre-loaded. app = get_qapp() d = Data(a=[1, 2, 3, 4, 5], b=[3.2, 1.2, 4.5, 3.3, 2.2], c=['e', 'b', 'c', 'a', 'f']) dc = DataCollection([d]) gapp = GlueApplication(dc) widget = gapp.new_data_viewer(TableViewer) widget.add_data(d) subset_mode = gapp._session.edit_subset_mode # Create two subsets sg1 = dc.new_subset_group('D <= 3', d.id['a'] <= 3) sg1.style.color = '#aa0000' sg2 = dc.new_subset_group('1 < D < 4', (d.id['a'] > 1) & (d.id['a'] < 4)) sg2.style.color = '#0000cc' model = widget.ui.table.model() # We now check what the data and colors of the table are, and try various # sorting methods to make sure that things are still correct. data = { 'a': [1, 2, 3, 4, 5], 'b': [3.2, 1.2, 4.5, 3.3, 2.2], 'c': ['e', 'b', 'c', 'a', 'f'] } colors = ['#aa0000', '#380088', '#380088', None, None] check_values_and_color(model, data, colors) model.sort(1, Qt.AscendingOrder) data = { 'a': [2, 5, 1, 4, 3], 'b': [1.2, 2.2, 3.2, 3.3, 4.5], 'c': ['b', 'f', 'e', 'a', 'c'] } colors = ['#380088', None, '#aa0000', None, '#380088'] check_values_and_color(model, data, colors) model.sort(2, Qt.AscendingOrder) data = { 'a': [4, 2, 3, 1, 5], 'b': [3.3, 1.2, 4.5, 3.2, 2.2], 'c': ['a', 'b', 'c', 'e', 'f'] } colors = [None, '#380088', '#380088', '#aa0000', None] check_values_and_color(model, data, colors) model.sort(0, Qt.DescendingOrder) data = { 'a': [5, 4, 3, 2, 1], 'b': [2.2, 3.3, 4.5, 1.2, 3.2], 'c': ['f', 'a', 'c', 'b', 'e'] } colors = [None, None, '#380088', '#380088', '#aa0000'] check_values_and_color(model, data, colors) model.sort(0, Qt.AscendingOrder) # We now modify the subsets using the table. selection = widget.ui.table.selectionModel() widget.toolbar.actions['table:rowselect'].toggle() def press_key(key): event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, key, Qt.NoModifier) app.postEvent(widget.ui.table, event) app.processEvents() app.processEvents() # We now use key presses to navigate down to the third row press_key(Qt.Key_Tab) press_key(Qt.Key_Down) press_key(Qt.Key_Down) indices = selection.selectedRows() # We make sure that the third row is selected assert len(indices) == 1 assert indices[0].row() == 2 # At this point, the subsets haven't changed yet np.testing.assert_equal(d.subsets[0].to_mask(), [1, 1, 1, 0, 0]) np.testing.assert_equal(d.subsets[1].to_mask(), [0, 1, 1, 0, 0]) # We specify that we are editing the second subset, and use a 'not' logical # operation to remove the currently selected line from the second subset. subset_mode.edit_subset = [d.subsets[1]] subset_mode.mode = AndNotMode press_key(Qt.Key_Enter) np.testing.assert_equal(d.subsets[0].to_mask(), [1, 1, 1, 0, 0]) np.testing.assert_equal(d.subsets[1].to_mask(), [0, 1, 0, 0, 0]) # At this point, the selection should be cleared indices = selection.selectedRows() assert len(indices) == 0 # We move to the fourth row and now do an 'or' selection with the first # subset. press_key(Qt.Key_Down) subset_mode.mode = OrMode subset_mode.edit_subset = [d.subsets[0]] press_key(Qt.Key_Enter) np.testing.assert_equal(d.subsets[0].to_mask(), [1, 1, 1, 1, 0]) np.testing.assert_equal(d.subsets[1].to_mask(), [0, 1, 0, 0, 0]) # Finally we move to the fifth row and deselect all subsets so that # pressing enter now creates a new subset. press_key(Qt.Key_Down) subset_mode.mode = ReplaceMode subset_mode.edit_subset = None press_key(Qt.Key_Enter) np.testing.assert_equal(d.subsets[0].to_mask(), [1, 1, 1, 1, 0]) np.testing.assert_equal(d.subsets[1].to_mask(), [0, 1, 0, 0, 0]) np.testing.assert_equal(d.subsets[2].to_mask(), [0, 0, 0, 0, 1]) # Make the color for the new subset deterministic dc.subset_groups[2].style.color = '#bababa' # Now finally check saving and restoring session session_file = tmpdir.join('table.glu').strpath gapp.save_session(session_file) gapp2 = GlueApplication.restore_session(session_file) gapp2.show() d = gapp2.data_collection[0] widget2 = gapp2.viewers[0][0] model2 = widget2.ui.table.model() data = { 'a': [1, 2, 3, 4, 5], 'b': [3.2, 1.2, 4.5, 3.3, 2.2], 'c': ['e', 'b', 'c', 'a', 'f'] } # Need to take into account new selections above colors = ['#aa0000', '#380088', '#aa0000', "#aa0000", "#bababa"] check_values_and_color(model2, data, colors)
pv_viewer = app.add_widget(pvwidget, label="Orbit PV Slice") ax2 = pvwidget.axes dl = (table['l'][1:]-table['l'][:-1]) db = (table['b'][1:]-table['b'][:-1]) dist = (dl**2+db**2)**0.5 cdist = np.zeros(dist.size+1) * u.deg cdist[1:] = dist.cumsum() * u.deg #pixscale = ((x[1]-x[0])**2+(y[1]-y[0])**2)**0.5 pixscale = wcs.utils.celestial_pixel_scale(cube.data.coords.wcs) spwcs = cube.data.coords.wcs.sub([wcs.WCSSUB_SPECTRAL]) spax = spwcs.wcs_world2pix(table["v'los"]*1e3, 0)[0] ax2.plot(cdist/pixscale, spax, 'r-', linewidth=2, alpha=0.5) ax2.set_axis_bgcolor('black') # SERIOUSLY, DO IT ax.axis([x.min(),x.max(),y.min(),y.max()]) dc.new_subset_group(label='T < 60', subset_state=subset_tem_lt_60) dc.new_subset_group(label='T > 60', subset_state=subset_tem_gt_60) dc.subset_groups[0].style.markersize=15 dc.subset_groups[0].style.marker='+' dc.subset_groups[0].style.color='blue' dc.subset_groups[1].style.markersize=15 dc.subset_groups[1].style.marker='*' dc.subset_groups[1].style.color='orange' app.start()
class TestExportPython(BaseTestExportPython): def setup_method(self, method): with NumpyRNGContext(12345): self.data = Data(**dict( (name, random_with_nan(100, nan_index=idx + 1)) for idx, name in enumerate('abcdefgh'))) self.data['angle'] = np.random.uniform(0, 360, 100) self.data_collection = DataCollection([self.data]) ga = GlueApplication(self.data_collection) self.viewer = ga.new_data_viewer(ScatterViewer) self.viewer.add_data(self.data) self.viewer.state.x_att = self.data.id['a'] self.viewer.state.y_att = self.data.id['b'] def test_simple(self, tmpdir): self.assert_same(tmpdir) def test_simple_nofill(self, tmpdir): if MATPLOTLIB_LT_20: pytest.xfail() self.viewer.state.layers[0].fill = False self.viewer.state.layers[0].size_scaling = 10 self.assert_same(tmpdir) def test_simple_visual(self, tmpdir): self.viewer.state.layers[0].color = 'blue' self.viewer.state.layers[0].markersize = 30 self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_cmap_mode(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_att = self.data.id['c'] self.viewer.state.layers[0].cmap = plt.cm.BuGn self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].alpha = 0.8 self.assert_same(tmpdir) def test_cmap_mode_nofill(self, tmpdir): self.viewer.state.layers[0].fill = False self.test_cmap_mode(tmpdir) def test_size_mode(self, tmpdir): self.viewer.state.layers[0].size_mode = 'Linear' self.viewer.state.layers[0].size_att = self.data.id['d'] self.viewer.state.layers[0].size_vmin = 0.1 self.viewer.state.layers[0].size_vmax = 0.8 self.viewer.state.layers[0].size_scaling = 0.4 self.viewer.state.layers[0].alpha = 0.7 self.assert_same(tmpdir) def test_size_mode_nofill(self, tmpdir): self.viewer.state.layers[0].fill = False self.test_size_mode(tmpdir) def test_line(self, tmpdir): self.viewer.state.layers[0].line_visible = True self.viewer.state.layers[0].linewidth = 10 self.viewer.state.layers[0].linestype = 'dashed' self.viewer.state.layers[0].color = 'orange' self.viewer.state.layers[0].alpha = 0.7 self.viewer.state.layers[0].markersize = 100 self.assert_same(tmpdir, tol=5) def test_line_cmap(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.test_line(tmpdir) def test_errorbarx(self, tmpdir): self.viewer.state.layers[0].xerr_visible = True self.viewer.state.layers[0].xerr_att = self.data.id['e'] self.viewer.state.layers[0].color = 'purple' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_errorbary(self, tmpdir): self.viewer.state.layers[0].yerr_visible = True self.viewer.state.layers[0].yerr_att = self.data.id['f'] self.viewer.state.layers[0].color = 'purple' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_errorbarxy(self, tmpdir): self.viewer.state.layers[0].xerr_visible = True self.viewer.state.layers[0].xerr_att = self.data.id['e'] self.viewer.state.layers[0].yerr_visible = True self.viewer.state.layers[0].yerr_att = self.data.id['f'] self.viewer.state.layers[0].color = 'purple' self.viewer.state.layers[0].alpha = 0.5 self.assert_same(tmpdir) def test_errorbarxy_cmap(self, tmpdir): if MATPLOTLIB_LT_20: pytest.xfail() self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.test_errorbarxy(tmpdir) def _vector_common(self, tmpdir): self.viewer.state.layers[0].vector_visible = True self.viewer.state.layers[0].vy_att = self.data.id['g'] self.viewer.state.layers[0].vector_arrowhead = True self.viewer.state.layers[0].vector_origin = 'tail' self.viewer.state.layers[0].vector_scaling = 1.5 self.viewer.state.layers[0].color = 'teal' self.viewer.state.layers[0].alpha = 0.9 self.assert_same(tmpdir) def test_vector_cartesian(self, tmpdir): self.viewer.state.layers[0].vector_mode = 'Cartesian' self.viewer.state.layers[0].vx_att = self.data.id['h'] self._vector_common(tmpdir) def test_vector_polar(self, tmpdir): self.viewer.state.layers[0].vector_mode = 'Polar' self.viewer.state.layers[0].vx_att = self.data.id['angle'] self._vector_common(tmpdir) def test_vector_cartesian_cmap(self, tmpdir): self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.test_vector_cartesian(tmpdir) def test_subset(self, tmpdir): self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_density_map_with_subset(self, tmpdir): self.viewer.state.dpi = 2 self.viewer.state.layers[0].density_map = True self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir) def test_density_map_cmap_with_subset(self, tmpdir): self.viewer.state.dpi = 2 self.viewer.state.layers[0].density_map = True self.viewer.state.layers[0].cmap_mode = 'Linear' self.viewer.state.layers[0].cmap_vmin = 0.2 self.viewer.state.layers[0].cmap_vmax = 0.7 self.viewer.state.layers[0].cmap = plt.cm.BuGn self.data_collection.new_subset_group('mysubset', self.data.id['a'] > 0.5) self.assert_same(tmpdir)
def setup_method(self, method): d = Data(x=[1, 2, 3]) dc = DataCollection([d]) self.collect = dc self.s = dc.new_subset_group()
def make_model(self, n_data=1, n_subsets=0): dc = DataCollection([Data(x=[1, 2, 3]) for _ in range(n_data)]) for _ in range(n_subsets): dc.new_subset_group() return DataCollectionModel(dc)
app = GlueApplication(dc) cube_viewer = app.new_data_viewer(ImageWidget) cube_viewer.add_data(h2cocube) h2cocube.join_on_key(dendro, 'structure', dendro.pixel_component_ids[0]) scatter = app.new_data_viewer(ScatterWidget) scatter.add_data(dendro) scatter.yatt = dendro.id['temperature_chi2'] scatter.xatt = catalog.id['r321303'] dendview = app.new_data_viewer(DendroWidget) dendview.add_data(dendro) subset_tem_bt_40_60 = ((catalog.id['temperature_chi2'] < 60) & (catalog.id['temperature_chi2'] > 40)) subset_tem_lt_40 = ((catalog.id['temperature_chi2'] < 40) & (catalog.id['temperature_chi2'] > 10)) subset_tem_gt_60 = (catalog.id['temperature_chi2'] > 60) sg0 = dc.new_subset_group(label='T < 40', subset_state=subset_tem_lt_40) sg1 = dc.new_subset_group(label='40 < T < 60', subset_state=subset_tem_bt_40_60) sg2 = dc.new_subset_group(label='T > 60', subset_state=subset_tem_gt_60) sg0.style.color = 'blue' sg1.style.color = 'green' sg2.style.color = 'red' #start Glue app.start()
class TestAstropyRegions: def setup_method(self, method): self.data = Data(flux=np.ones((128, 256))) self.dc = DataCollection([self.data]) def test_rectangular_roi(self): subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(1, 3.5, -0.2, 3.3)) self.dc.new_subset_group(subset_state=subset_state, label='rectangular') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 2.25) assert_allclose(reg.center.y, 1.55) assert_allclose(reg.width, 2.5) assert_allclose(reg.height, 3.5) def test_polygonal_roi(self): xv = [1.3, 2, 3, 1.5, 0.5] yv = [10, 20.20, 30, 25, 17.17] subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], PolygonalROI(xv, yv)) self.dc.new_subset_group(subset_state=subset_state, label='polygon') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, PolygonPixelRegion) assert_array_equal(reg.vertices.x, xv) assert_array_equal(reg.vertices.y, yv) def test_circular_roi(self): subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], CircularROI(1, 3.5, 0.75)) self.dc.new_subset_group(subset_state=subset_state, label='circular') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CirclePixelRegion) assert_equal(reg.center.x, 1) assert_equal(reg.center.y, 3.5) assert_equal(reg.radius, 0.75) def test_point_roi(self): subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], PointROI(2.64, 5.4)) self.dc.new_subset_group(subset_state=subset_state, label='point') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, PointPixelRegion) assert_equal(reg.center.x, 2.64) assert_equal(reg.center.y, 5.4) def test_xregion_roi(self): subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], XRangeROI(1, 3.5)) self.dc.new_subset_group(subset_state=subset_state, label='xrangeroi') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 2.25) assert_allclose(reg.center.y, 64) assert_allclose(reg.width, 2.5) assert_allclose(reg.height, 128) def test_yregion_roi(self): subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], YRangeROI(10, 22.2)) self.dc.new_subset_group(subset_state=subset_state, label='xrangeroi') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 128) assert_allclose(reg.center.y, 16.1) assert_allclose(reg.width, 256) assert_allclose(reg.height, 12.2) def test_mpl_roi(self): rect_roi = RectangularROI(1, 3.5, -0.2, 3.3) subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], AbstractMplRoi(None, rect_roi)) self.dc.new_subset_group(subset_state=subset_state, label='mpl_rectangular') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 2.25) assert_allclose(reg.center.y, 1.55) assert_allclose(reg.width, 2.5) assert_allclose(reg.height, 3.5) def test_horiz_range_subset(self): subset_state = RangeSubsetState(26, 27.5, self.data.pixel_component_ids[1]) self.dc.new_subset_group(subset_state=subset_state, label='horizrange') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 26.75) assert_allclose(reg.center.y, 64) assert_allclose(reg.width, 1.5) assert_allclose(reg.height, 128) def test_vert_range_subset(self): subset_state = RangeSubsetState(105.5, 107.7, self.data.pixel_component_ids[0]) self.dc.new_subset_group(subset_state=subset_state, label='vertrange') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 128) assert_allclose(reg.center.y, 106.6) assert_allclose(reg.width, 256) assert_allclose(reg.height, 2.2) def test_invalid_range_subset(self): subset_state = RangeSubsetState(0, 1, self.data.main_components[0]) self.dc.new_subset_group(subset_state=subset_state, label='invalidrange') with pytest.raises(ValueError) as exc: self.data.get_selection_definition(format='astropy-regions') expect_message = 'Range subset state att should be either x or y pixel coordinate' assert exc.value.args[0] == expect_message def test_horiz_multirange(self): subset_state = MultiRangeSubsetState([(26, 27.5), (28, 29)], self.data.pixel_component_ids[1]) self.dc.new_subset_group(subset_state=subset_state, label='horizmultirange') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert reg.contains(PixCoord(26.4, 54.6)) assert reg.contains(PixCoord(28.26, 75.5)) assert not reg.contains(PixCoord(27.75, 34)) rect1 = reg.region1 assert isinstance(rect1, RectanglePixelRegion) assert_allclose(rect1.center.x, 26.75) assert_allclose(rect1.center.y, 64) assert_allclose(rect1.width, 1.5) assert_allclose(rect1.height, 128) rect2 = reg.region2 assert isinstance(rect2, RectanglePixelRegion) assert_allclose(rect2.center.x, 28.5) assert_allclose(rect2.center.y, 64) assert_allclose(rect2.width, 1) assert_allclose(rect2.height, 128) def test_vert_multirange(self): subset_state = MultiRangeSubsetState([(30, 33.5), (21, 27)], self.data.pixel_component_ids[0]) self.dc.new_subset_group(subset_state=subset_state, label='horizmultirange') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert reg.contains(PixCoord(145, 31.2)) assert reg.contains(PixCoord(32, 24.6)) assert not reg.contains(PixCoord(128, 29.2)) rect1 = reg.region1 assert isinstance(rect1, RectanglePixelRegion) assert_allclose(rect1.center.x, 128) assert_allclose(rect1.center.y, 31.75) assert_allclose(rect1.width, 256) assert_allclose(rect1.height, 3.5) rect2 = reg.region2 assert isinstance(rect2, RectanglePixelRegion) assert_allclose(rect2.center.x, 128) assert_allclose(rect2.center.y, 24) assert_allclose(rect2.width, 256) assert_allclose(rect2.height, 6) def test_invalid_multiranges(self): wrong_att = MultiRangeSubsetState([(30, 33.5), (21, 27)], self.data.main_components[0]) empty = MultiRangeSubsetState([], self.data.pixel_component_ids[0]) self.dc.new_subset_group(subset_state=wrong_att, label='wrong_att') self.dc.new_subset_group(subset_state=empty, label='empty') with pytest.raises(ValueError) as exc: self.data.get_selection_definition(subset_id='wrong_att', format='astropy-regions') expect_message = 'Multirange subset state att should be either x or y pixel coordinate' assert exc.value.args[0] == expect_message with pytest.raises(ValueError) as exc: self.data.get_selection_definition(subset_id='empty', format='astropy-regions') assert exc.value.args[ 0] == 'Multirange subset state should contain at least one range' def test_pixel_subset(self): slices = [slice(15, 16, None), slice(130, 131, None)] # Correspond to pixel (130,15) subset_state = PixelSubsetState(self.data, slices) self.dc.new_subset_group(subset_state=subset_state, label='pixel_subset') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, PointPixelRegion) assert_equal(reg.center.x, 130) assert_equal(reg.center.y, 15) def test_and_region(self): subset_state1 = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(1, 5, 2, 6)) subset_state2 = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], CircularROI(4.75, 5.75, 0.5)) and_subset_state = AndState(subset_state1, subset_state2) self.dc.new_subset_group(subset_state=and_subset_state, label='andstate') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert isinstance(reg.region1, RectanglePixelRegion) assert isinstance(reg.region2, CirclePixelRegion) assert reg.contains(PixCoord(4.5, 5.5)) assert not reg.contains(PixCoord(3, 4)) assert not reg.contains(PixCoord(5.1, 6.1)) assert not reg.contains(PixCoord(11, 12)) def test_or_region(self): subset_state1 = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(1, 5, 2, 6)) subset_state2 = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], CircularROI(4.75, 5.75, 0.5)) or_subset_state = OrState(subset_state1, subset_state2) self.dc.new_subset_group(subset_state=or_subset_state, label='orstate') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert isinstance(reg.region1, RectanglePixelRegion) assert isinstance(reg.region2, CirclePixelRegion) assert reg.contains(PixCoord(4.5, 5.5)) assert reg.contains(PixCoord(3, 4)) assert reg.contains(PixCoord(5.1, 6.1)) assert not reg.contains(PixCoord(11, 12)) def test_xor_region(self): subset_state1 = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(1, 5, 2, 6)) subset_state2 = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], CircularROI(4.75, 5.75, 0.5)) xor_subset_state = XorState(subset_state1, subset_state2) self.dc.new_subset_group(subset_state=xor_subset_state, label='xorstate') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert isinstance(reg.region1, RectanglePixelRegion) assert isinstance(reg.region2, CirclePixelRegion) assert not reg.contains(PixCoord(4.5, 5.5)) assert reg.contains(PixCoord(3, 4)) assert reg.contains(PixCoord(5.1, 6.1)) assert not reg.contains(PixCoord(11, 12)) def test_multior_region(self): rects = [(1, 2, 3, 4), (1.5, 2.5, 3.5, 4.5), (2, 3, 4, 5)] states = [ RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(*rect)) for rect in rects ] multior_subset_state = MultiOrState(states) self.dc.new_subset_group(subset_state=multior_subset_state, label='multiorstate') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert isinstance(reg.region1, CompoundPixelRegion) assert isinstance(reg.region2, RectanglePixelRegion) assert isinstance(reg.region1.region1, RectanglePixelRegion) assert isinstance(reg.region1.region2, RectanglePixelRegion) assert reg.contains(PixCoord(1.25, 3.25)) assert reg.contains(PixCoord(1.75, 3.75)) assert reg.contains(PixCoord(2.25, 3.75)) assert reg.contains(PixCoord(2.25, 4.25)) assert reg.contains(PixCoord(2.75, 4.75)) assert not reg.contains(PixCoord(5, 7)) # The following test fails because the logical operations should now work? @pytest.mark.xfail def test_invalid_combos(self): good_subset = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(1, 5, 2, 6)) bad_subset = RoiSubsetState(self.data.pixel_component_ids[1], self.data.main_components[0], CircularROI(4.75, 5.75, 0.5)) and_sub = AndState(good_subset, bad_subset) or_sub = OrState(good_subset, bad_subset) xor_sub = XorState(good_subset, bad_subset) multior = MultiOrState([good_subset, bad_subset]) self.dc.new_subset_group(subset_state=and_sub, label='and') self.dc.new_subset_group(subset_state=or_sub, label='or') self.dc.new_subset_group(subset_state=xor_sub, label='xor') self.dc.new_subset_group(subset_state=multior, label='multior') expected_error = 'Subset state yatt should be y pixel coordinate' with pytest.raises(ValueError) as exc: self.data.get_selection_definition(subset_id='and', format='astropy-regions') assert exc.value.args[0] == expected_error with pytest.raises(ValueError) as exc: self.data.get_selection_definition(subset_id='or', format='astropy-regions') assert exc.value.args[0] == expected_error with pytest.raises(ValueError) as exc: self.data.get_selection_definition(subset_id='xor', format='astropy-regions') assert exc.value.args[0] == expected_error with pytest.raises(ValueError) as exc: self.data.get_selection_definition(subset_id='multior', format='astropy-regions') assert exc.value.args[0] == expected_error def test_reordered_pixel_components(self): self.data._pixel_component_ids = self.data._pixel_component_ids[::-1] range_state = RangeSubsetState(105.5, 107.7, self.data.pixel_component_ids[1]) self.dc.new_subset_group(subset_state=range_state, label='reordered_range') rect_state = RoiSubsetState(self.data.pixel_component_ids[0], self.data.pixel_component_ids[1], RectangularROI(1, 3.5, -0.2, 3.3)) self.dc.new_subset_group(subset_state=rect_state, label='reordered_rectangular') range_region = self.data.get_selection_definition( subset_id='reordered_range', format='astropy-regions') rect_region = self.data.get_selection_definition( subset_id='reordered_rectangular', format='astropy-regions') assert isinstance(range_region, RectanglePixelRegion) assert_allclose(range_region.center.x, 128) assert_allclose(range_region.center.y, 106.6) assert_allclose(range_region.width, 256) assert_allclose(range_region.height, 2.2) assert isinstance(rect_region, RectanglePixelRegion) assert_allclose(rect_region.center.x, 2.25) assert_allclose(rect_region.center.y, 1.55) assert_allclose(rect_region.width, 2.5) assert_allclose(rect_region.height, 3.5) def test_subset_id(self): subset_state = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(1, 3.5, -0.2, 3.3)) self.dc.new_subset_group(subset_state=subset_state, label='rectangular') for subset_id in [None, 0, 'rectangular']: reg = self.data.get_selection_definition(format='astropy-regions', subset_id=subset_id) assert isinstance(reg, RectanglePixelRegion) assert_allclose(reg.center.x, 2.25) assert_allclose(reg.center.y, 1.55) assert_allclose(reg.width, 2.5) assert_allclose(reg.height, 3.5) with pytest.raises(ValueError) as exc: self.data.get_selection_definition(format='astropy-regions', subset_id='circular') assert exc.value.args[0] == "No subset found with the label 'circular'" def test_unsupported(self): self.dc.new_subset_group(subset_state=self.data.id['flux'] > 0.5, label='Flux-based selection') with pytest.raises(NotImplementedError) as exc: self.data.get_selection_definition( format='astropy-regions', subset_id='Flux-based selection') assert exc.value.args[ 0] == 'Subset states of type InequalitySubsetState are not supported'
def make_model(self, n_data=1, n_subsets=0): dc = DataCollection([Data(x=[1, 2, 3]) for _ in range(n_data)]) for _ in range(n_subsets): dc.new_subset_group() return DataCollectionModel(dc)
class TestSaveDataDialog: def setup_method(self, method): self.data1 = Data(x=[1, 2, 3], y=[2, 3, 4], label='data1') self.data2 = Data(a=[1, 2, 3], b=[2, 3, 4], label='data2') self.dc = DataCollection([self.data1, self.data2]) self.dc.new_subset_group(label='my subset', subset_state=self.data1.id['x'] > 1.5) self.x = self.data1.id['x'] self.y = self.data1.id['y'] self.a = self.data2.id['a'] self.b = self.data2.id['b'] self.app = get_qapp() self.dialog = SaveDataDialog(data_collection=self.dc) def teardown_method(self, method): self.app = None def test_defaults(self): disabled, enabled = components(self.dialog.ui.list_component) assert enabled == ['x', 'y'] assert disabled == [] def test_defaults_derived(self): self.data1['z'] = self.data1.id['x'] + 1 disabled, enabled = components(self.dialog.ui.list_component) assert enabled == ['x', 'y', 'z'] assert disabled == [] def test_change_data(self): self.dialog.ui.combosel_data.setCurrentIndex(1) disabled, enabled = components(self.dialog.ui.list_component) assert enabled == ['a', 'b'] assert disabled == [] def test_select_buttons(self): self.dialog.button_select_none.click() disabled, enabled = components(self.dialog.ui.list_component) assert enabled == [] assert disabled == ['x', 'y'] self.dialog.button_select_all.click() disabled, enabled = components(self.dialog.ui.list_component) assert enabled == ['x', 'y'] assert disabled == [] def test_accept(self): func = self._accept() func.assert_called_once_with('test_file.fits', self.data1, components=[self.x, self.y]) def test_change_accept(self): self.dialog.ui.combosel_data.setCurrentIndex(1) func = self._accept() func.assert_called_once_with('test_file.fits', self.data2, components=[self.a, self.b]) def test_change_subset_accept(self): self.dialog.ui.combosel_subset.setCurrentIndex(1) func = self._accept() func.assert_called_once_with('test_file.fits', self.data1.subsets[0], components=[self.x, self.y]) def test_deselect_accept(self): self.dialog.ui.list_component.item(1).setCheckState(Qt.Unchecked) func = self._accept() func.assert_called_once_with('test_file.fits', self.data1, components=[self.x]) def test_deselect_all(self): self.dialog.select_none() assert not self.dialog.button_ok.isEnabled() self.dialog.select_all() assert self.dialog.button_ok.isEnabled() def _accept(self): mock = MagicMock() test_exporter_cls = namedtuple('exporter', 'function label extension') test_exporter = test_exporter_cls(function=mock, label='Test', extension='') with patch('qtpy.compat.getsavefilename') as dialog: with patch('glue.config.data_exporter') as data_exporter: def test_iter(x): yield test_exporter data_exporter.__iter__ = test_iter dialog.return_value = 'test_file.fits', None self.dialog.state._sync_data_exporters() self.dialog.accept() return test_exporter.function
self.layer_combo.setEnabled(True) # Set up contents of combo box labeldata = [] # First include the dataset itself labeldata.append(('Full dataset', self.data)) for subset in self.data.subsets: labeldata.append((subset.label, subset)) update_combobox(self.layer_combo, labeldata) if __name__ == "__main__": from glue.utils.qt import get_qapp from glue.core import Data, DataCollection data_collection = DataCollection() data = Data(x=[1, 2, 3], label='banana') data_collection.append(data) data_collection.new_subset_group('a', data.id['x'] > 0) app = get_qapp() widget = SimpleLayerWidget() widget.show() widget.data = data app.exec_()
def setup_method(self, method): d = Data(x=[1, 2, 3]) dc = DataCollection([d]) self.collect = dc self.s = dc.new_subset_group()
self.layer_combo.setEnabled(True) # Set up contents of combo box labeldata = [] # First include the dataset itself labeldata.append(('Full dataset', self.data)) for subset in self.data.subsets: labeldata.append((subset.label, subset)) update_combobox(self.layer_combo, labeldata) if __name__ == "__main__": from glue.utils.qt import get_qapp from glue.core import Data, DataCollection data_collection = DataCollection() data = Data(x=[1, 2, 3], label='banana') data_collection.append(data) data_collection.new_subset_group('a', data.id['x'] > 0) app = get_qapp() widget = SimpleLayerWidget() widget.show() widget.data = data app.exec_()