diff --git a/orangecontrib/text/widgets/owtopicmodeling.py b/orangecontrib/text/widgets/owtopicmodeling.py index 4903bc777..f21ca7608 100644 --- a/orangecontrib/text/widgets/owtopicmodeling.py +++ b/orangecontrib/text/widgets/owtopicmodeling.py @@ -130,12 +130,15 @@ class Outputs: hdp = settings.SettingProvider(HdpWidget) lda = settings.SettingProvider(LdaWidget) + selection = settings.Setting(None, schema_only=True) + control_area_width = 300 def __init__(self): super().__init__() self.corpus = None self.learning_thread = None + self.__pending_selection = self.selection # Commit button gui.auto_commit(self.buttonsArea, self, 'autocommit', 'Commit', box=False) @@ -200,7 +203,8 @@ def apply(self): @asynchronous def learning_task(self): - return self.model.fit_transform(self.corpus.copy(), chunk_number=100, on_progress=self.on_progress) + return self.model.fit_transform(self.corpus.copy(), chunk_number=100, + on_progress=self.on_progress) @learning_task.on_start def on_start(self): @@ -217,6 +221,9 @@ def on_result(self, corpus): self.Outputs.all_topics.send(None) else: self.topic_desc.show_model(self.model) + if self.__pending_selection: + self.topic_desc.select(self.__pending_selection) + self.__pending_selection = None self.Outputs.all_topics.send(self.model.get_all_topics_table()) @learning_task.callback @@ -229,8 +236,10 @@ def send_report(self): self.report_items('Topics', self.topic_desc.report()) def send_topic_by_id(self, topic_id=None): + self.selection = topic_id if self.model.model and topic_id is not None: - self.Outputs.selected_topic.send(self.model.get_topics_table_by_id(topic_id)) + self.Outputs.selected_topic.send( + self.model.get_topics_table_by_id(topic_id)) class TopicViewerTreeWidgetItem(QTreeWidgetItem): @@ -274,6 +283,7 @@ def __init__(self): self.resize_columns() self.itemSelectionChanged.connect(self.selected_topic_changed) self.setItemDelegate(HTMLDelegate()) # enable colors + self.selected_id = None def resize_columns(self): for i in range(self.columnCount()): @@ -296,9 +306,8 @@ def show_model(self, topic_model): def selected_topic_changed(self): selected = self.selectedItems() if selected: - topic_id = selected[0].topic_id - self.setCurrentItem(self.topLevelItem(topic_id)) - self.topicSelected.emit(topic_id) + self.select(selected[0].topic_id) + self.topicSelected.emit(self.selected_id) else: self.topicSelected.emit(None) @@ -311,6 +320,10 @@ def report(self): def sizeHint(self): return QSize(700, 300) + def select(self, index): + self.selected_id = index + self.setCurrentItem(self.topLevelItem(index)) + class HTMLDelegate(QStyledItemDelegate): """ This delegate enables coloring of words in QTreeWidgetItem. diff --git a/orangecontrib/text/widgets/tests/test_owtopicmodeling.py b/orangecontrib/text/widgets/tests/test_owtopicmodeling.py new file mode 100644 index 000000000..418d2426b --- /dev/null +++ b/orangecontrib/text/widgets/tests/test_owtopicmodeling.py @@ -0,0 +1,59 @@ +import itertools +import unittest + +import numpy as np +from AnyQt.QtCore import QItemSelectionModel + +from Orange.widgets.tests.base import WidgetTest +from orangecontrib.text.corpus import Corpus +from orangecontrib.text.widgets.owtopicmodeling import OWTopicModeling + + +class TestTopicModeling(WidgetTest): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.corpus = Corpus.from_file('deerwester') + + def setUp(self): + self.widget = self.create_widget(OWTopicModeling) + + def test_data(self): + def until(): + return bool(self.get_output(self.widget.Outputs.selected_topic)) + + self.send_signal(self.widget.Inputs.corpus, self.corpus) + self.process_events(until) + + self.send_signal(self.widget.Inputs.corpus, None) + output = self.get_output(self.widget.Outputs.selected_topic) + self.assertIsNone(output) + + def test_saved_selection(self): + def until(widget=self.widget): + return bool(self.get_output(widget.Outputs.selected_topic, + widget=widget)) + + self.send_signal(self.widget.Inputs.corpus, self.corpus) + self.process_events(until) + idx = self.widget.topic_desc.model().index(2, 0) + self.widget.topic_desc.selectionModel().select( + idx, QItemSelectionModel.Rows | QItemSelectionModel.ClearAndSelect) + output1 = self.get_output(self.widget.Outputs.selected_topic) + state = self.widget.settingsHandler.pack_data(self.widget) + + w = self.create_widget(OWTopicModeling, stored_settings=state) + self.send_signal(w.Inputs.corpus, self.corpus, widget=w) + self.process_events(lambda: until(w)) + output2 = self.get_output(w.Outputs.selected_topic, widget=w) + # gensim uses quicksort, so sorting is unstable + m1 = output1.metas[output1.metas[:, 0].argsort()] + m2 = output2.metas[output2.metas[:, 0].argsort()] + # test words and weights separately, weights are not exactly equal + self.assertTrue((m1[:, 0] == m2[:, 0]).all()) + np.testing.assert_allclose(m1[:, 1].astype(float), + m2[:, 1].astype(float)) + + +if __name__ == "__main__": + unittest.main()