Changeset 1882:5f55ddc19cea in orange-bioinformatics


Ignore:
Timestamp:
10/11/13 11:38:34 (6 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

Added an option to select genes in a secondary data table input.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • orangecontrib/bio/widgets/OWSelectGenes.py

    r1873 r1882  
    77 
    88from PyQt4.QtGui import ( 
    9     QLabel, QWidget, QPlainTextEdit, QSyntaxHighlighter, QTextCharFormat, 
    10     QTextCursor, QCompleter, QStringListModel, QListView 
     9    QFrame, QHBoxLayout, QPlainTextEdit, QSyntaxHighlighter, QTextCharFormat, 
     10    QTextCursor, QCompleter, QStringListModel, QStandardItemModel, 
     11    QStandardItem, QListView, QStyle, QStyledItemDelegate, 
     12    QStyleOptionViewItemV4, QPalette, QColor, QApplication, 
     13    QAction, QToolButton, QSizePolicy, QItemSelectionModel, 
     14    QPlainTextDocumentLayout, QTextDocument, QRadioButton, 
     15    QButtonGroup, QStyleOptionButton 
    1116) 
    1217 
    13 from PyQt4.QtCore import Qt, QEvent, pyqtSignal as Signal 
     18from PyQt4.QtCore import Qt, QEvent, QVariant, pyqtSignal as Signal 
    1419 
    1520import Orange 
    1621 
    17 from Orange.OrangeWidgets.OWWidget import * 
     22from Orange.OrangeWidgets.OWWidget import \ 
     23    OWWidget, DomainContextHandler, Default 
     24 
    1825from Orange.OrangeWidgets.OWItemModels import VariableListModel 
    1926from Orange.OrangeWidgets import OWGUI 
     
    2431ICON = "icons/SelectGenes.svg" 
    2532 
    26 INPUTS = [("Data", Orange.data.Table, "setData")] 
     33INPUTS = [("Data", Orange.data.Table, "setData", Default), 
     34          ("Gene Subset", Orange.data.Table, "setGeneSubset")] 
     35 
    2736OUTPUTS = [("Selected Data", Orange.data.Table)] 
    2837 
     
    8796 
    8897 
     98def radio_indicator_width(button): 
     99    button.ensurePolished() 
     100    style = button.style() 
     101    option = QStyleOptionButton() 
     102    button.initStyleOption(option) 
     103 
     104    w = style.pixelMetric(QStyle.PM_ExclusiveIndicatorWidth, option, button) 
     105    return w 
     106 
     107 
    89108class OWSelectGenes(OWWidget): 
    90109 
     
    92111        "": DomainContextHandler( 
    93112            "", ["geneIndex"] 
     113        ), 
     114        "subset": DomainContextHandler( 
     115            "subset", ["subsetGeneIndex"] 
    94116        ) 
    95117    } 
    96118 
    97119    settingsList = ["autoCommit", "preserveOrder", "savedSelections", 
    98                     "selectedSelectionIndex"] 
     120                    "selectedSelectionIndex", "selectedSource"] 
     121 
     122    SelectInput, SelectCustom = 0, 1 
    99123 
    100124    def __init__(self, parent=None, signalManager=None, title=NAME): 
     
    110134 
    111135        self.selectedSelectionIndex = -1 
     136        self.selectedSource = OWSelectGenes.SelectCustom 
    112137 
    113138        self.loadSettings() 
     
    119144        # Output changed flag 
    120145        self._changedFlag = False 
    121         self.data = None 
    122146        # Current gene names 
    123147        self.selection = [] 
     148        # Input data 
     149        self.data = None 
     150        self.subsetData = None 
     151        # Input variables that could contain gene names from "Gene Subset" 
     152        self.subsetVariables = VariableListModel() 
     153        # Selected subset variable index 
     154        self.subsetGeneIndex = -1 
    124155 
    125156        box = OWGUI.widgetBox(self.controlArea, "Gene Attribute") 
     157        box.setToolTip("Column with gene names") 
    126158        self.attrsCombo = OWGUI.comboBox( 
    127159            box, self, "geneIndex", 
    128160            callback=self._onGeneIndexChanged, 
    129             tooltip="Column with gene names" 
    130161        ) 
    131162        self.attrsCombo.setModel(self.variables) 
    132163 
    133164        box = OWGUI.widgetBox(self.controlArea, "Gene Selection") 
     165 
     166        button1 = QRadioButton("Select genes from 'Gene Subset' input") 
     167        button2 = QRadioButton("Select specified genes") 
     168 
     169        box.layout().addWidget(button1) 
     170 
     171        # Subset gene variable selection 
     172        self.subsetbox = OWGUI.widgetBox(box, None) 
     173        offset = radio_indicator_width(button1) 
     174        self.subsetbox.layout().setContentsMargins(offset, 0, 0, 0) 
     175        self.subsetbox.setEnabled( 
     176            self.selectedSource == OWSelectGenes.SelectInput) 
     177 
     178        self.subsetVarCombo = OWGUI.comboBox( 
     179            OWGUI.widgetBox(self.subsetbox, "Gene Attribute", flat=True), 
     180            self, "subsetGeneIndex", 
     181            callback=self._onSubsetGeneIndexChanged 
     182        ) 
     183        self.subsetVarCombo.setModel(self.subsetVariables) 
     184        self.subsetVarCombo.setToolTip( 
     185            "Column with gene names in the 'Gene Subset' input" 
     186        ) 
     187 
     188        box.layout().addWidget(button2) 
     189 
     190        group = QButtonGroup(box) 
     191        group.addButton(button1, OWSelectGenes.SelectInput) 
     192        group.addButton(button2, OWSelectGenes.SelectCustom) 
     193        group.buttonClicked[int].connect(self._selectionSourceChanged) 
     194 
     195        if self.selectedSource == OWSelectGenes.SelectInput: 
     196            button1.setChecked(True) 
     197        else: 
     198            button2.setChecked(True) 
     199 
     200        self.entrybox = OWGUI.widgetBox(box, None) 
     201        offset = radio_indicator_width(button2) 
     202        self.entrybox.layout().setContentsMargins(offset, 0, 0, 0) 
     203 
     204        self.entrybox.setEnabled( 
     205            self.selectedSource == OWSelectGenes.SelectCustom) 
     206 
     207        box = OWGUI.widgetBox(self.entrybox, "Select Genes", flat=True) 
     208        box.setToolTip("Enter gene names to select") 
     209 
    134210        self.entryField = ListTextEdit(box) 
    135211        self.entryField.setTabChangesFocus(True) 
    136         self.entryField.setToolTip("Enter selected gene names") 
    137212        self.entryField.setDocument(self._createDocument()) 
    138213        self.entryField.itemsChanged.connect(self._onItemsChanged) 
     
    149224        self.entryField.setCompleter(completer) 
    150225 
    151         box = OWGUI.widgetBox(self.controlArea, "Saved Selections") 
     226        box = OWGUI.widgetBox(self.entrybox, "Saved Selections", flat=True) 
     227        box.setToolTip("Save/Select/Update saved gene selections") 
    152228        box.layout().setSpacing(1) 
    153229 
     
    163239        box.layout().addWidget(self.selectionsView) 
    164240 
    165         self.actionSave = QAction("Save", self) 
    166         self.actionAdd = QAction("+", self) 
    167         self.actionRemove = QAction("-", self) 
     241        self.actionSave = QAction( 
     242            "Save", self, 
     243            toolTip="Save/Update the current selection") 
     244 
     245        self.actionAdd = QAction( 
     246            "+", self, 
     247            toolTip="Create a new saved selection") 
     248 
     249        self.actionRemove = QAction( 
     250            "-", self, 
     251            toolTip="Delete the current saved selection") 
    168252 
    169253        toolbar = QFrame() 
     
    222306        """ 
    223307        self.closeContext("") 
    224         self.warning() 
     308        self.warning(0) 
    225309        self.data = data 
    226310        if data is not None: 
     
    244328        self.commit() 
    245329 
     330    def setGeneSubset(self, data): 
     331        """ 
     332        Set the gene subset input. 
     333        """ 
     334        self.closeContext("subset") 
     335        self.warning(1) 
     336        self.subsetData = data 
     337        if data is not None: 
     338            variables = gene_candidates(data) 
     339            self.subsetVariables[:] = variables 
     340            self.subsetVarCombo.setCurrentIndex(0) 
     341            if variables: 
     342                self.subsetGeneIndex = 0 
     343            else: 
     344                self.subsetGeneIndex = -1 
     345                self.warning(1, "No suitable column for subset gene names.") 
     346        else: 
     347            self.subsetVariables[:] = [] 
     348            self.subsetGeneIndex = -1 
     349 
     350        self.openContext("subset", data) 
     351 
     352        if self.selectedSource == OWSelectGenes.SelectInput: 
     353            self.commit() 
     354 
    246355    @property 
    247356    def geneVar(self): 
     
    249358        Current gene attribute or None if none available. 
    250359        """ 
    251         if self.data is not None and self.geneIndex >= 0: 
    252             return self.variables[self.geneIndex] 
     360        index = self.attrsCombo.currentIndex() 
     361        if self.data is not None and index >= 0: 
     362            return self.variables[index] 
     363        else: 
     364            return None 
     365 
     366    @property 
     367    def subsetGeneVar(self): 
     368        """ 
     369        Current subset gene attribute or None if not available. 
     370        """ 
     371        index = self.subsetVarCombo.currentIndex() 
     372        if self.subsetData is not None and index >= 0: 
     373            return self.subsetVariables[index] 
    253374        else: 
    254375            return None 
     
    260381            self._changedFlag = True 
    261382 
     383    def selectedGenes(self): 
     384        """ 
     385        Return the names of the current selected genes. 
     386        """ 
     387        selection = [] 
     388        if self.selectedSource == OWSelectGenes.SelectInput: 
     389            var = self.subsetGeneVar 
     390            if var is not None: 
     391                values = [inst[var] for inst in self.subsetData] 
     392                selection = [str(val) for val in values 
     393                             if not val.is_special()] 
     394        else: 
     395            selection = self.selection 
     396        return selection 
     397 
    262398    def commit(self): 
    263399        """ 
    264400        Send the selected data subset to the output. 
    265401        """ 
    266         gene = self.geneVar 
    267  
    268         if gene is not None: 
    269             data = select_by_genes(self.data, gene, 
    270                                    gene_list=self.selection, 
     402        selection = self.selectedGenes() 
     403 
     404        if self.geneVar is not None: 
     405            data = select_by_genes(self.data, self.geneVar, 
     406                                   gene_list=selection, 
    271407                                   preserve_order=self.preserveOrder) 
    272408        else: 
     
    275411        self.send("Selected Data", data) 
    276412        self._changedFlag = False 
     413 
     414    def _selectionSourceChanged(self, source): 
     415        if self.selectedSource != source: 
     416            self.selectedSource = source 
     417            self.subsetbox.setEnabled(source == OWSelectGenes.SelectInput) 
     418            self.entrybox.setEnabled(source == OWSelectGenes.SelectCustom) 
     419            self.invalidateOutput() 
    277420 
    278421    def _updateCompletionModel(self): 
     
    280423        if var is not None: 
    281424            names = [str(inst[var]) for inst in self.data 
    282                      if not inst[var].isSpecial()] 
     425                     if not inst[var].is_special()] 
    283426        else: 
    284427            names = [] 
     
    291434        self._updateCompletionModel() 
    292435        self.invalidateOutput() 
     436 
     437    def _onSubsetGeneIndexChanged(self): 
     438        if self.selectedSource == OWSelectGenes.SelectInput: 
     439            self.invalidateOutput() 
    293440 
    294441    def _onItemsChanged(self, names): 
     
    412559            self.addToReportList(item) 
    413560        self.finishReportList() 
    414         self.reportRaw( 
    415             "<p>Gene Selection: %s</p>" % 
    416             escape(" ".join(self.selection)) 
    417         ) 
     561        report = [] 
     562        selection = self.selectedGenes() 
     563        if self.selectedSource == OWSelectGenes.SelectInput: 
     564            self.reportRaw( 
     565                "<p>Gene Selection (from 'Gene Subset' input): %s</p>" % 
     566                escape(" ".join(selection)) 
     567            ) 
     568        else: 
     569            self.reportRaw( 
     570                "<p>Gene Selection: %s</p>" % 
     571                escape(" ".join(selection)) 
     572            ) 
    418573        self.reportSettings( 
    419574            "Settings", 
     
    786941    data = Orange.data.Table("brown-selected") 
    787942    w.setData(data) 
     943    w.setGeneSubset(Orange.data.Table(data[:10])) 
    788944    w.show() 
    789945    app.exec_() 
Note: See TracChangeset for help on using the changeset viewer.