def test_sorting(self): assert issubclass(PyTableModel, AbstractSortTableModel) model = PyTableModel([[1, 4], [2, 2], [3, 3]]) model.sort(1, Qt.AscendingOrder) # mapToSourceRows self.assertSequenceEqual( model.mapToSourceRows(...).tolist(), [1, 2, 0]) self.assertEqual(model.mapToSourceRows(1).tolist(), 2) self.assertSequenceEqual( model.mapToSourceRows([1, 2]).tolist(), [2, 0]) self.assertSequenceEqual(model.mapToSourceRows([]), []) self.assertSequenceEqual( model.mapToSourceRows(np.array([], dtype=int)).tolist(), []) self.assertRaises(IndexError, model.mapToSourceRows, np.r_[0.]) # mapFromSourceRows self.assertSequenceEqual( model.mapFromSourceRows(...).tolist(), [2, 0, 1]) self.assertEqual(model.mapFromSourceRows(1).tolist(), 0) self.assertSequenceEqual( model.mapFromSourceRows([1, 2]).tolist(), [0, 1]) self.assertSequenceEqual(model.mapFromSourceRows([]), []) self.assertSequenceEqual( model.mapFromSourceRows(np.array([], dtype=int)).tolist(), []) self.assertRaises(IndexError, model.mapFromSourceRows, np.r_[0.]) model.sort(1, Qt.DescendingOrder) self.assertSequenceEqual( model.mapToSourceRows(...).tolist(), [0, 2, 1]) self.assertSequenceEqual( model.mapFromSourceRows(...).tolist(), [0, 2, 1])
def test_sorting(self): assert issubclass(PyTableModel, AbstractSortTableModel) model = PyTableModel([[1, 4], [2, 2], [3, 3]]) model.sort(1, Qt.AscendingOrder) # mapToSourceRows self.assertSequenceEqual(model.mapToSourceRows(...).tolist(), [1, 2, 0]) self.assertEqual(model.mapToSourceRows(1).tolist(), 2) self.assertSequenceEqual(model.mapToSourceRows([1, 2]).tolist(), [2, 0]) self.assertSequenceEqual(model.mapToSourceRows([]), []) self.assertSequenceEqual(model.mapToSourceRows(np.array([], dtype=int)).tolist(), []) self.assertRaises(IndexError, model.mapToSourceRows, np.r_[0.]) # mapFromSourceRows self.assertSequenceEqual(model.mapFromSourceRows(...).tolist(), [2, 0, 1]) self.assertEqual(model.mapFromSourceRows(1).tolist(), 0) self.assertSequenceEqual(model.mapFromSourceRows([1, 2]).tolist(), [0, 1]) self.assertSequenceEqual(model.mapFromSourceRows([]), []) self.assertSequenceEqual(model.mapFromSourceRows(np.array([], dtype=int)).tolist(), []) self.assertRaises(IndexError, model.mapFromSourceRows, np.r_[0.]) model.sort(1, Qt.DescendingOrder) self.assertSequenceEqual(model.mapToSourceRows(...).tolist(), [0, 2, 1]) self.assertSequenceEqual(model.mapFromSourceRows(...).tolist(), [0, 2, 1])
class OWRankSurvivalFeatures(OWWidget, ConcurrentWidgetMixin): name = 'Rank Survival Features' # TODO: Add widget metadata description = '' icon = 'icons/owranksurvivalfeatures.svg' priority = 30 keywords = [] buttons_area_orientation = Qt.Vertical select_none, manual_selection, select_n_best = range(3) settingsHandler = DomainContextHandler() selected_attrs = ContextSetting([], schema_only=True) selection_method = Setting(select_n_best, schema_only=True) n_selected = Setting(20, schema_only=True) auto_commit: bool = Setting(False, schema_only=True) class Inputs: data = Input('Data', Table) class Outputs: reduced_data = Output('Reduced Data', Table, default=True) def __init__(self): OWWidget.__init__(self) ConcurrentWidgetMixin.__init__(self) self.data: Optional[Table] = None self.attr_name_to_variable: Optional[Table] = None self.covariates_from_worker_result = None self.time_var: Optional[str] = None self.event_var: Optional[str] = None gui.rubber(self.controlArea) sel_method_box = gui.vBox(self.buttonsArea, 'Select Attributes') grid = QGridLayout() grid.setContentsMargins(0, 0, 0, 0) grid.setSpacing(6) self.select_buttons = QButtonGroup() self.select_buttons.buttonClicked[int].connect( self.set_selection_method) def button(text, buttonid, toolTip=None): b = QRadioButton(text) self.select_buttons.addButton(b, buttonid) if toolTip is not None: b.setToolTip(toolTip) return b b1 = button(self.tr('None'), OWRankSurvivalFeatures.select_none) b2 = button(self.tr('Manual'), OWRankSurvivalFeatures.manual_selection) b3 = button(self.tr('Best ranked:'), OWRankSurvivalFeatures.select_n_best) s = gui.spin( sel_method_box, self, 'n_selected', 1, 999, callback=lambda: self.set_selection_method(OWRankSurvivalFeatures. select_n_best), addToLayout=False, ) grid.addWidget(b1, 0, 0) grid.addWidget(b2, 1, 0) grid.addWidget(b3, 2, 0) grid.addWidget(s, 2, 1) sel_method_box.layout().addLayout(grid) self.commit_button = gui.auto_commit(self.buttonsArea, self, 'auto_commit', '&Commit', box=False) # Main area self.model = PyTableModel(parent=self) self.table_view = TableView(parent=self) self.table_view.setModel(self.model) self.model.setHorizontalHeaderLabels([ 'Log-Likelihood', 'Log-Likelihood Ratio', f'{"p".center(13)}', 'FDR' ]) self.table_view.setSizeAdjustPolicy( QAbstractScrollArea.AdjustToContentsOnFirstShow) self.table_view.selectionModel().selectionChanged.connect( self.on_select) def _set_select_manual(): self.set_selection_method(OWRankSurvivalFeatures.manual_selection) self.table_view.manualSelection.connect(_set_select_manual) self.table_view.verticalHeader().sectionClicked.connect( _set_select_manual) self.mainArea.layout().addWidget(self.table_view) @property def covariates(self) -> Optional[List[str]]: if not self.data: return return [attr.name for attr in self.data.domain.attributes] @Inputs.data @check_survival_data def set_data(self, data: Table): self.closeContext() self.selected_attrs = [] self.covariates_from_worker_result = [] self.model.clear() self.model.resetSorting() if not data: return self.data = data self.attr_name_to_variable = { attr.name: attr for attr in self.data.domain.attributes } self.openContext(data) time_var, event_var = get_survival_endpoints(self.data.domain) self.time_var, self.event_var = time_var.name, event_var.name self.start(worker, self.data, self.covariates, self.time_var, self.event_var) def commit(self): if not self.selected_attrs: self.Outputs.reduced_data.send(None) else: reduced_domain = Domain(self.selected_attrs, self.data.domain.class_vars, self.data.domain.metas) data = self.data.transform(reduced_domain) self.Outputs.reduced_data.send(data) def on_done(self, worker_result): covariate_names, results = worker_result # wrap everything except covariate names self.model.wrap(results.tolist()) # this is temp solution because covariate orders gets mixed when using multiprocessing self.covariates_from_worker_result = covariate_names.tolist() # match covariate names to domain variables and set vertical header self.model.setVerticalHeaderLabels( [self.attr_name_to_variable[name] for name in covariate_names]) self.table_view.resizeColumnsToContents() self.auto_select() def on_exception(self, ex): raise ex def on_partial_result(self, result: Any) -> None: pass def set_selection_method(self, method): self.selection_method = method self.select_buttons.button(method).setChecked(True) self.auto_select() def auto_select(self): selection_model = self.table_view.selectionModel() row_count = self.model.rowCount() column_count = self.model.columnCount() if self.selection_method == OWRankSurvivalFeatures.select_none: selection = QItemSelection() elif self.selection_method == OWRankSurvivalFeatures.select_n_best: n_selected = min(self.n_selected, row_count) selection = QItemSelection( self.model.index(0, 0), self.model.index(n_selected - 1, column_count - 1)) else: selection = QItemSelection() if self.selected_attrs is not None: attr_indices = [ self.covariates_from_worker_result.index(var.name) for var in self.selected_attrs ] for row in self.model.mapFromSourceRows(attr_indices): selection.append( QItemSelectionRange( self.model.index(row, 0), self.model.index(row, column_count - 1))) selection_model.select(selection, QItemSelectionModel.ClearAndSelect) def on_select(self): selected_rows = self.table_view.selectionModel().selectedRows(0) row_indices = [i.row() for i in selected_rows] attr_indices = self.model.mapToSourceRows(row_indices) self.selected_attrs = [ self.model._headers[Qt.Vertical][row] for row in attr_indices ] self.commit()