Commits

Aleš Erjavec committed 28b8737

Gene Info widget code style fixes.

  • Participants
  • Parent commits 2370b27

Comments (0)

Files changed (1)

orangecontrib/bio/widgets/OWGeneInfo.py

 
 from PyQt4.QtCore import pyqtSlot as Slot
 
-from Orange.orng import orngServerFiles
+import Orange
+
+from Orange.utils import serverfiles
+from Orange.utils import lru_cache
+
 from Orange.orng.orngDataCaching import data_hints
 from Orange.OrangeWidgets import OWGUI
+from Orange.OrangeWidgets.OWGUI import LinkStyledItemDelegate, LinkRole
+
 from Orange.OrangeWidgets.OWWidget import *
 
 from Orange.OrangeWidgets.OWConcurrent import \
     ThreadExecutor, Task, methodinvoke
 
-from Orange.utils import progress_bar_milestones
-
 import orange
 
 from .. import obiGene, obiTaxonomy
 
 
 class TreeModel(QAbstractItemModel):
+
     def __init__(self, data, header, parent):
         QAbstractItemModel.__init__(self, parent)
         self._data = [[QVariant(s) for s in row] for row in data]
         self._dataDict = {}
         self._header = header
-        self._roleData = {Qt.DisplayRole:self._data}
-        self._roleData = partial(defaultdict, partial(defaultdict, partial(defaultdict, QVariant)))(self._roleData)
-    
+        self._roleData = {Qt.DisplayRole: self._data}
+        self._roleData = partial(
+            defaultdict,
+            partial(defaultdict,
+                    partial(defaultdict, QVariant)))(self._roleData)
+
     def setColumnLinks(self, column, links):
-        font =QFont()
+        font = QFont()
         font.setUnderline(True)
         font = QVariant(font)
         for i, link in enumerate(links):
             self._roleData[LinkRole][i][column] = QVariant(link)
             self._roleData[Qt.FontRole][i][column] = font
-            self._roleData[Qt.ForegroundRole][i][column] = QVariant(QColor(Qt.blue))
-    
+            self._roleData[Qt.ForegroundRole][i][column] = \
+                QVariant(QColor(Qt.blue))
+
     def setRoleData(self, role, row, col, data):
         self._roleData[role][row][col] = data
-        
+
     def data(self, index, role=Qt.DisplayRole):
         row, col = index.row(), index.column()
         return self._roleData[role][row][col]
-        
+
     def index(self, row, col, parent=QModelIndex()):
         return self.createIndex(row, col, 0)
-    
+
     def parent(self, index):
         return QModelIndex()
-    
+
     def rowCount(self, index=QModelIndex()):
         if index.isValid():
             return 0
         else:
             return len(self._data)
-        
+
     def columnCount(self, index=QModelIndex()):
         return len(self._header)
 
     def headerData(self, section, orientation, role=Qt.DisplayRole):
-        if role==Qt.DisplayRole:
+        if role == Qt.DisplayRole:
             return QVariant(self._header[section])
         return QVariant()
 
-from Orange.OrangeWidgets.OWGUI import LinkStyledItemDelegate, LinkRole
 
-def lru_cache(maxsize=100):
-    """ A least recently used cache function decorator.
-    """
-    
-    def decorating_function(func):
-        import functools
-        cache = {}
-        
-        @functools.wraps(func)
-        def wrapped(*args, **kwargs):
-            key = args + tuple(sorted(kwargs.items()))
-            if key not in cache:
-                res = func(*args, **kwargs)
-                cache[key] = (time.time(), res)
-                if len(cache) > maxsize:
-                    key, (_, _) = min(cache.iteritems(), key=lambda item: item[1][0])
-                    del cache[key]
-            else:
-                _, res = cache[key]
-                cache[key] = (time.time(), res) # update the time
-                
-            return res
-        
-        def clear():
-            cache.clear()
-        
-        wrapped.clear = clear
-        
-        return wrapped
-    return decorating_function
-                
 class LinkFmt(object):
+
     def __init__(self, link_fmt, name):
         self.link_fmt = link_fmt
         self.name = name
-        
+
     def format(self, *args, **kwargs):
         return Link(self.link_fmt.format(*args, **kwargs), **kwargs)
-    
+
     def __repr__(self):
         return "<LinkFmt " + repr(self.name) + " >"
-    
+
     def __str__(self):
         return self.name
-    
+
+
 class Link(object):
+
     def __init__(self, link, text=None, **kwargs):
         self.link = link
         self.text = text if text is not None else "link"
         self.__dict__.update(kwargs)
-        
-    def str(self):
-        return link
-    
-    
+
+
 @lru_cache(maxsize=2)
 def get_ncbi_info(taxid):
     return obiGene.NCBIGeneInfo(taxid)
 
+
 def ncbi_info(taxid, genes):
     info = get_ncbi_info(taxid)
-    schema_link = LinkFmt("http://www.ncbi.nlm.nih.gov/sites/entrez?Db=gene&Cmd=ShowDetailView&TermToSearch={gene_id}", name="NCBI ID")
+    schema_link = LinkFmt(
+        "http://www.ncbi.nlm.nih.gov/sites/entrez?Db=gene&Cmd=ShowDetailView&TermToSearch={gene_id}",
+        name="NCBI ID")
+
     schema = [schema_link, "Symbol", "Locus Tag", "Chromosome",
               "Description", "Synonyms", "Nomenclature"]
     ret = []
         else:
             ret.append(None)
     return schema, ret
-    
+
+
 def dicty_info(taxid, genes):
-    from .. import obiDicty 
+    from .. import obiDicty
     info = obiDicty.DictyBase()
     name_matcher = obiGene.GMDicty()
     name_matcher.set_targets(info.info.keys())
     schema_link = LinkFmt("http://dictybase.org/db/cgi-bin/gene_page.pl?dictybaseid={gene_id}", name="Dicty Base Id")
     schema = [schema_link, "Name", "Synonyms", "Gene Products"]
-    
+
     ret = []
     for gene in genes:
         gene = name_matcher.umatch(gene)
         gi = info.info.get(gene, None)
         if gi:
             ret.append([schema_link.format(gene_id=gene, text=gene),
-                        gi[0] + " (%s)" % gene if gene != gi[0] else gi[0], # Gene Name
-                        ", ".join(gi[1]), # Synonyms
-                        gi[2] or "", # Gene Products
+                        gi[0] + " (%s)" % gene if gene != gi[0] else gi[0],  # Gene Name
+                        ", ".join(gi[1]),  # Synonyms
+                        gi[2] or "",  # Gene Products
                         ])
-            
+
         else:
             ret.append(None)
-    
+
     return schema, ret
 
 
 #                            debuggingEnabled=0,
                             )
         self.altSourceCheck.hide()
-        
+
         box = OWGUI.widgetBox(self.controlArea, "Gene names", addSpace=True)
-        self.geneAttrComboBox = OWGUI.comboBox(box, self, "geneAttr",
-                                "Gene atttibute", callback=self.updateInfoItems)
-        
-        c = OWGUI.checkBox(box, self, "useAttr", "Use attribute names",
-                           callback=self.updateInfoItems,
-                           disables=[(-1, self.geneAttrComboBox)])
-        
+        self.geneAttrComboBox = OWGUI.comboBox(
+            box, self, "geneAttr",
+            "Gene atttibute", callback=self.updateInfoItems
+        )
+        OWGUI.checkBox(box, self, "useAttr", "Use attribute names",
+                       callback=self.updateInfoItems,
+                       disables=[(-1, self.geneAttrComboBox)])
+
         self.geneAttrComboBox.setDisabled(bool(self.useAttr))
 
         box = OWGUI.widgetBox(self.controlArea, "Commit", addSpace=True)
         c = OWGUI.checkBox(box, self, "autoCommit", "Commit on change")
         OWGUI.setStopper(self, b, c, "selectionChangedFlag",
                          callback=self.commit)
-        
-        ## A label for dictyExpress link
-        self.dictyExpressBox = OWGUI.widgetBox(self.controlArea, "Dicty Express")
+
+        # A label for dictyExpress link
+        self.dictyExpressBox = OWGUI.widgetBox(
+            self.controlArea, "Dicty Express")
         self.linkLabel = OWGUI.widgetLabel(self.dictyExpressBox, "")
         self.linkLabel.setOpenExternalLinks(False)
         self.connect(self.linkLabel, SIGNAL("linkActivated(QString)"),
                      self.onDictyExpressLink)
         self.dictyExpressBox.hide()
-        
+
         OWGUI.rubber(self.controlArea)
 
         OWGUI.lineEdit(self.mainArea, self, "searchString", "Filter",
                        callbackOnType=True, callback=self.searchUpdate)
-        
+
         self.treeWidget = QTreeView(self.mainArea)
         self.treeWidget.setRootIsDecorated(False)
-        self.treeWidget.setSelectionMode(QAbstractItemView.ExtendedSelection)
-        self.treeWidget.setItemDelegate(LinkStyledItemDelegate(self.treeWidget))
+        self.treeWidget.setSelectionMode(
+            QAbstractItemView.ExtendedSelection)
+        self.treeWidget.setItemDelegate(
+            LinkStyledItemDelegate(self.treeWidget))
         self.treeWidget.setUniformRowHeights(True)
         self.treeWidget.viewport().setMouseTracking(True)
         self.treeWidget.setSortingEnabled(True)
         self.mainArea.layout().addWidget(self.treeWidget)
-        
+
         box = OWGUI.widgetBox(self.mainArea, "",
                               orientation="horizontal")
         OWGUI.button(box, self, "Select Filtered",
                      callback=self.selectFiltered)
         OWGUI.button(box, self, "Clear Selection",
                      callback=self.treeWidget.clearSelection)
-        
+
         self.resize(1000, 700)
 
         self.geneinfo = []
         self.row2geneinfo = {}
         self.data = None
 
-        #: (# input genes, # matches genes)
+        # : (# input genes, # matches genes)
         self.matchedInfo = 0, 0
         self.selectionUpdateInProgress = False
 
 
         self.organisms = sorted(
             set([name.split(".")[-2] for name in
-                 orngServerFiles.listfiles("NCBI_geneinfo")] +
+                 serverfiles.listfiles("NCBI_geneinfo")] +
                 obiGene.NCBIGeneInfo.essential_taxids())
         )
 
 
         if data:
             self.geneAttrComboBox.clear()
-            self.attributes = [attr for attr in self.data.domain.variables + \
-                               self.data.domain.getmetas().values() \
+            self.attributes = [attr for attr in data.domain.variables +
+                               data.domain.getmetas().values()
                                if attr.varType in [orange.VarTypes.String,
                                                    orange.VarTypes.Discrete]]
-            self.geneAttrComboBox.addItems([attr.name for attr in self.attributes])
+            self.geneAttrComboBox.addItems(
+                [attr.name for attr in self.attributes]
+            )
 
             self.taxid = data_hints.get_hint(self.data, "taxid", self.taxid)
-            self.useAttr = data_hints.get_hint(self.data, "genesinrows",  self.useAttr)
+            self.useAttr = data_hints.get_hint(
+                self.data, "genesinrows", self.useAttr)
 
             self.openContext("", data)
             self.geneAttr = min(self.geneAttr, len(self.attributes) - 1)
             if self.taxid in self.organisms:
                 self.organismIndex = self.organisms.index(self.taxid)
 
-            self.useAttr = data_hints.get_hint(self.data, "genesinrows",  self.useAttr)
-
             self.updateInfoItems()
         else:
             self.clear()
 
     def infoSource(self):
-        """ Return the current selected info source getter function from 
+        """ Return the current selected info source getter function from
         INFO_SOURCES
         """
         org = self.organisms[min(self.organismIndex, len(self.organisms) - 1)]
         if org not in INFO_SOURCES:
             org = "default"
         sources = INFO_SOURCES[org]
-        name, func =  sources[min(self.useAltSource, len(sources) - 1)]
+        name, func = sources[min(self.useAltSource, len(sources) - 1)]
         return name, func
 
     def inputGenes(self):
             genes = [attr.name for attr in self.data.domain.attributes]
         elif self.attributes:
             attr = self.attributes[self.geneAttr]
-            genes = [str(ex[attr]) for ex in self.data if not ex[attr].isSpecial()]
+            genes = [str(ex[attr]) for ex in self.data
+                     if not ex[attr].isSpecial()]
         else:
             genes = []
         return genes
             genes = [attr.name for attr in self.data.domain.attributes]
         elif self.attributes:
             attr = self.attributes[self.geneAttr]
-            genes = [str(ex[attr]) for ex in self.data if not ex[attr].isSpecial()]
+            genes = [str(ex[attr]) for ex in self.data
+                     if not ex[attr].isSpecial()]
         else:
             genes = []
         if not genes:
 
         for i in range(7):
             self.treeWidget.resizeColumnToContents(i)
-            self.treeWidget.setColumnWidth(i, min(self.treeWidget.columnWidth(i), 200))
+            self.treeWidget.setColumnWidth(
+                i, min(self.treeWidget.columnWidth(i), 200)
+            )
 
         self.infoLabel.setText("%i genes\n%i matched NCBI's IDs" %
                                (len(self.genes), len(cells)))
 
     def clear(self):
         self.infoLabel.setText("No data on input\n")
-        self.treeWidget.setModel(TreeModel([], ["NCBI ID", "Symbol", "Locus Tag",
-                                            "Chromosome", "Description", "Synonyms",
-                                            "Nomenclature"], self.treeWidget))
+        self.treeWidget.setModel(
+            TreeModel([], ["NCBI ID", "Symbol", "Locus Tag",
+                           "Chromosome", "Description", "Synonyms",
+                           "Nomenclature"], self.treeWidget))
+
         self.geneAttrComboBox.clear()
         self.send("Selected Examples", None)
 
             return
         model = self.treeWidget.model()
         mapToSource = model.mapToSource
-        selectedIds = [self.cells[mapToSource(index).row()][0] for index in self.treeWidget.selectedIndexes()]
         selectedRows = self.treeWidget.selectedIndexes()
         selectedRows = [mapToSource(index).row() for index in selectedRows]
         model = model.sourceModel()
-        
+
         selectedGeneids = [self.row2geneinfo[row] for row in selectedRows]
         selectedIds = [self.geneinfo[i][0] for i in selectedGeneids]
         selectedIds = set(selectedIds)
-        gene2row = dict((self.geneinfo[self.row2geneinfo[row]][0], row) \
+        gene2row = dict((self.geneinfo[self.row2geneinfo[row]][0], row)
                         for row in selectedRows)
-        
+
         if self.useAttr:
             def is_selected(attr):
                 return attr.name in selectedIds
-            attrs = [attr for attr in self.data.domain.attributes if is_selected(attr)]
+            attrs = [attr for attr in self.data.domain.attributes
+                     if is_selected(attr)]
             domain = orange.Domain(attrs, self.data.domain.classVar)
             domain.addmetas(self.data.domain.getmetas())
             newdata = orange.ExampleTable(domain, self.data)
             self.send("Selected Examples", newdata)
         elif self.attributes:
             attr = self.attributes[self.geneAttr]
-            geneinfo = dict(self.geneinfo)
             examples = [ex for ex in self.data if str(ex[attr]) in selectedIds]
             if True:  # Add gene info
-                domain = orange.Domain(self.data.domain, self.data.domain.classVar)
+                domain = orange.Domain(self.data.domain,
+                                       self.data.domain.classVar)
                 domain.addmetas(self.data.domain.getmetas())
                 n_columns = model.columnCount()
 
-                headers = [str(model.headerData(i, Qt.Horizontal, Qt.DisplayRole).toString()) \
+                headers = [str(model.headerData(i, Qt.Horizontal, Qt.DisplayRole).toString())
                            for i in range(n_columns)]
-                new_meta_attrs = [(orange.newmetaid(), orange.StringVariable(name)) \
+                new_meta_attrs = [(orange.newmetaid(), orange.StringVariable(name))
                                   for name in headers]
                 domain.addmetas(dict(new_meta_attrs))
                 examples = [orange.Example(domain, ex) for ex in examples]
             self.send("Selected Examples", newdata)
         else:
             self.send("Selected Examples", None)
-            
+
     def rowFiltered(self, row):
         searchStrings = self.searchString.lower().split()
         row = unicode(" ".join(self.cells[row]).lower(), errors="ignore")
         return not all([s in row for s in searchStrings])
-    
+
     def searchUpdate(self):
         if not self.data:
             return
         mapFromSource = self.treeWidget.model().mapFromSource
         for i, row in enumerate(self.cells):
             row = unicode(" ".join(row).lower(), errors="ignore")
-            self.treeWidget.setRowHidden(mapFromSource(index(i, 0)).row(), QModelIndex(), not all([s in row for s in searchStrings]))
-        #self.treeWidget.model().setFilterRegExp(QRegExp(self.searchString, Qt.CaseInsensitive, QRegExp.FixedString))
-            
+            self.treeWidget.setRowHidden(
+                mapFromSource(index(i, 0)).row(),
+                QModelIndex(),
+                not all([s in row for s in searchStrings]))
+
     def selectFiltered(self):
         if not self.data:
             return
         itemSelection = QItemSelection()
-        
+
         index = self.treeWidget.model().sourceModel().index
         mapFromSource = self.treeWidget.model().mapFromSource
         for i, row in enumerate(self.cells):
             if not self.rowFiltered(i):
-                itemSelection.select(mapFromSource(index(i, 0)), mapFromSource(index(i, 0)))
-        self.treeWidget.selectionModel().select(itemSelection, QItemSelectionModel.Select | QItemSelectionModel.Rows)
-        
+                itemSelection.select(mapFromSource(index(i, 0)),
+                                     mapFromSource(index(i, 0)))
+        self.treeWidget.selectionModel().select(
+            itemSelection,
+            QItemSelectionModel.Select | QItemSelectionModel.Rows)
+
     def sendReport(self):
         from Orange.OrangeWidgets import OWReport
         genes, matched = self.matchedInfo
 
     def updateDictyExpressLink(self, genes, show=False):
         def fix(ddb):
-            if ddb.startswith("DDB"): 
+            if ddb.startswith("DDB"):
                 if not ddb.startswith("DDB_G"):
                     ddb = ddb.replace("DDB", "DDB_G")
                 return ddb
-            return None 
+            return None
         if show:
             genes = [fix(gene) for gene in genes if fix(gene)]
             link1 = '<a href="http://dictyexpress.biolab.si/run/index.php?gene=%s">Microarray profile</a>'
             link2 = '<a href="http://dictyexpress.biolab.si/run/index.php?gene=%s&db=rnaseq">RNA-Seq profile</a>'
             self.linkLabel.setText(link1 + "<br/>" + link2)
-            
+
             show = any(genes)
-                
+
         if show:
             self.dictyExpressBox.show()
         else:
 
         selectedIndexes = self.treeWidget.selectedIndexes()
         if not len(selectedIndexes):
-            QMessageBox.information(self, "No gene ids selected", "Please select some genes and try again.")
+            QMessageBox.information(
+                self, "No gene ids selected",
+                "Please select some genes and try again."
+            )
             return
         model = self.treeWidget.model()
         mapToSource = model.mapToSource
-        selectedIds = [self.cells[mapToSource(index).row()][0] for index in selectedIndexes]
         selectedRows = self.treeWidget.selectedIndexes()
         selectedRows = [mapToSource(index).row() for index in selectedRows]
         model = model.sourceModel()
         genes = [fix(gene) for gene in selectedIds if fix(gene)]
         url = str(link) % " ".join(genes)
         QDesktopServices.openUrl(QUrl(url))
-            
+
     def onAltSourceChange(self):
         self.updateInfoItems()
 
 def reportItemView(view):
     model = view.model()
     return reportItemModel(view, model)
-    
+
+
 def reportItemModel(view, model, index=QModelIndex()):
     if not index.isValid() or model.hasChildren(index):
         columnCount, rowCount = model.columnCount(index), model.rowCount(index)
         if not index.isValid():
-            text = '<table>\n<tr>' + ''.join('<th>%s</th>' % model.headerData(i, Qt.Horizontal, Qt.DisplayRole).toString() for i in range(columnCount)) +'</tr>\n'
+            text = ('<table>\n<tr>' +
+                    ''.join('<th>%s</th>' %
+                            model.headerData(i, Qt.Horizontal, Qt.DisplayRole)
+                            .toString()
+                            for i in range(columnCount)) +
+                    '</tr>\n')
         else:
-#            variant = model.data(index, Qt.DisplayRole)
-#            text = '<table' + (' caption="%s"' % variant.toString() if variant.isValid() else '') + '>\n'
             pass
-        text += ''.join('<tr>' + ''.join('<td>' + reportItemModel(view, model, model.index(row, column, index)) + '</td>' for column in range(columnCount)) + '</tr>\n' for row in range(rowCount) if not view.isRowHidden(row, index))
+        text += ''.join('<tr>' +
+                        ''.join('<td>' + reportItemModel(view, model, model.index(row, column, index)) +
+                                '</td>' for column in range(columnCount)) +
+                        '</tr>\n'
+                        for row in range(rowCount)
+                        if not view.isRowHidden(row, index))
         text += '</table>'
         return text
     else:
         variant = model.data(index, Qt.DisplayRole)
         return str(variant.toString()) if variant.isValid() else ""
-        
+
+
 if __name__ == "__main__":
     app = QApplication(sys.argv)
     data = orange.ExampleTable("brown-selected.tab")