source: orange-bioinformatics/_bioinformatics/widgets/OWSetEnrichment.py @ 1761:d8f3d4bb64fa

Revision 1761:d8f3d4bb64fa, 26.3 KB checked in by Flashpoint <vid.flashpoint@…>, 12 months ago (diff)

Added obiDictyMutants.py

RevLine 
[1478]1"""<name>Gene Set Enrichment</name>
[1726]2<icon>icons/GeneSetEnrichment.svg</icon>
[1478]3"""
4
[1632]5from __future__ import absolute_import, with_statement
[1478]6
7import math
8from collections import defaultdict
9
[1632]10from Orange.orng import orngEnviron, orngServerFiles
11from Orange.orng.orngDataCaching import data_hints
12from Orange.OrangeWidgets import OWGUI
13from Orange.OrangeWidgets.OWGUI import LinkStyledItemDelegate, LinkRole
14from Orange.OrangeWidgets.OWGUI import BarItemDelegate
15from Orange.OrangeWidgets.OWWidget import *
16
17from .. import obiGene, obiGeneSets, obiProb, obiTaxonomy
[1478]18
[1498]19def _toPyObject(variant):
20    val = variant.toPyObject()
21    if isinstance(val, type(NotImplemented)): # PyQt 4.4 converts python int, floats ... to C types
22        qtype = variant.type()
23        if qtype == QVariant.Double:
24            val, ok = variant.toDouble()
25        elif qtype == QVariant.Int:
26            val, ok = variant.toInt()
27        elif qtype == QVariant.LongLong:
28            val, ok = variant.toLongLong()
29        elif qtype == QVariant.String:
30            val = variant.toString()
31    return val
[1478]32
33class MyTreeWidget(QTreeWidget):
34    def paintEvent(self, event):
35        QTreeWidget.paintEvent(self, event)
36        if getattr(self, "_userMessage", None):
37            painter = QPainter(self.viewport())
38            font = QFont(self.font())
39            font.setPointSize(15)
40            painter.setFont(font)
41            painter.drawText(self.viewport().geometry(), Qt.AlignCenter, self._userMessage)
42            painter.end()
[1761]43
[1498]44class MyTreeWidgetItem(QTreeWidgetItem):
45    def __lt__(self, other):
46        if not self.treeWidget():
47            return id(self) < id(other)
48        column = self.treeWidget().sortColumn()
49        lhs = _toPyObject(self.data(column, Qt.DisplayRole))
50        rhs = _toPyObject(other.data(column, Qt.DisplayRole))
51        return lhs < rhs
[1761]52
[1574]53def name_or_none(id):
54    """Return organism name for ncbi taxid or None if not found.
55    """
56    try:
57        return obiTaxonomy.name(id)
58    except obiTaxonomy.UnknownSpeciesIdentifier:
59        return None
[1761]60
[1478]61class OWSetEnrichment(OWWidget):
62    settingsList = ["speciesIndex", "genesinrows", "geneattr", "categoriesCheckState"]
63    contextHandlers = {"":DomainContextHandler("", ["speciesIndex", "genesinrows", "geneattr", "categoriesCheckState"])}
[1761]64
[1498]65    def __init__(self, parent=None, signalManager=None, name="Gene Set Enrichment Analysis", **kwargs):
[1478]66        OWWidget.__init__(self, parent, signalManager, name, **kwargs)
67        self.inputs = [("Example Table", ExampleTable, self.setData, Default), ("Reference", ExampleTable, self.setReference)]
68        self.outputs = [("Selected Examples", ExampleTable)]
[1761]69
[1478]70        self.speciesIndex = 0
71        self.genesinrows = False
72        self.geneattr = 0
73        self.geneMatcherSettings = [False, False, True, False]
74        self.useReferenceData = False
75        self.useMinCountFilter = True
76        self.useMaxPValFilter = True
77        self.minClusterCount = 0
78        self.maxPValue = 0.01
[1761]79
[1478]80        self.useFDR = True
[1761]81
[1478]82        self.categoriesCheckState = {}
[1761]83
[1478]84        self.loadSettings()
[1761]85
[1748]86        if self.signalManager:
87            self.signalManager.freeze(self).push()
[1478]88        QTimer.singleShot(50, self.updateHierarchy)
[1761]89
[1478]90        box = OWGUI.widgetBox(self.controlArea, "Info")
91        self.infoBox = OWGUI.widgetLabel(box, "Info")
92        self.infoBox.setText("No data on input")
[1761]93
[1478]94        self.speciesComboBox = OWGUI.comboBox(self.controlArea, self,
95                      "speciesIndex", "Species",
96                      callback=lambda :self.data and self.updateAnnotations(),
97                      debuggingEnabled=0)
[1761]98
[1478]99        box = OWGUI.widgetBox(self.controlArea, "Gene names")
100        self.geneAttrComboBox = OWGUI.comboBox(box, self, "geneattr",
101                                "Gene attribute",
102                                sendSelectedValue=0,
103                                callback=self.updateAnnotations)
[1761]104
[1478]105        cb = OWGUI.checkBox(box, self, "genesinrows", "Use attribute names",
106                            callback=lambda :self.data and self.updateAnnotations(),
107                            disables=[(-1, self.geneAttrComboBox)])
108        cb.makeConsistent()
[1761]109
[1478]110        OWGUI.button(box, self, "Gene matcher settings",
111                     callback=self.updateGeneMatcherSettings,
112                     tooltip="Open gene matching settings dialog",
113                     debuggingEnabled=0)
[1761]114
[1478]115        self.referenceRadioBox = OWGUI.radioButtonsInBox(self.controlArea,
116                    self, "useReferenceData", ["Entire genome", "Reference set (input)"],
117                    tooltips=["Use entire genome for reference",
118                              "Use genes from Referece Examples input signal as reference"],
119                    box="Reference", callback=self.updateAnnotations)
[1761]120
121        box = OWGUI.widgetBox(self.controlArea, "Gene Sets")
[1478]122        self.groupsWidget = QTreeWidget(self)
123        self.groupsWidget.setHeaderLabels(["Category"])
124        box.layout().addWidget(self.groupsWidget)
125
126        hLayout = QHBoxLayout()
127        hLayout.setSpacing(10)
[1498]128        hWidget = OWGUI.widgetBox(self.mainArea, orientation=hLayout)
129        sb, sbcb = OWGUI.spin(hWidget, self, "minClusterCount",
[1761]130                              0, 100, label="Genes",
[1478]131                              tooltip="Minimum gene count",
132                              callback=self.filterAnnotationsChartView,
133                              callbackOnReturn=True,
134                              checked="useMinCountFilter",
135                              checkCallback=self.filterAnnotationsChartView)
[1761]136
[1498]137        dsp, dspcb = OWGUI.doubleSpin(hWidget, self,
[1478]138                        "maxPValue", 0.0, 1.0, 0.0001,
[1761]139                        label="P-Value (FDR corrected)",
[1478]140                        tooltip="Maximum (FDR corrected) P-Value",
141                        callback=self.filterAnnotationsChartView,
142                        callbackOnReturn=True,
143                        checked="useMaxPValFilter",
144                        checkCallback=self.filterAnnotationsChartView)
[1761]145
[1632]146        from Orange.OrangeWidgets import OWGUIEx
[1478]147        self.filterLineEdit = OWGUIEx.QLineEditWithActions(self)
148        self.filterLineEdit.setPlaceholderText("Filter ...")
149        action = QAction(QIcon(os.path.join(orngEnviron.canvasDir,
150                        "icons", "delete_gray.png")), "Clear", self)
[1761]151
[1478]152        self.filterLineEdit.addAction(action, 0, Qt.AlignHCenter)
153        self.connect(action, SIGNAL("triggered()"), self.filterLineEdit.clear)
[1761]154
[1478]155        self.filterCompleter = QCompleter(self.filterLineEdit)
156        self.filterCompleter.setCaseSensitivity(Qt.CaseInsensitive)
157        self.filterLineEdit.setCompleter(self.filterCompleter)
[1761]158
[1478]159        hLayout.addWidget(self.filterLineEdit)
[1498]160        self.mainArea.layout().addWidget(hWidget)
[1761]161
[1478]162        self.connect(self.filterLineEdit, SIGNAL("textChanged(QString)"),
163                     self.filterAnnotationsChartView)
[1761]164
[1478]165        self.annotationsChartView = MyTreeWidget(self)
166        self.annotationsChartView.setHeaderLabels(["Category", "Term",
167                            "Count", "Reference count", "P-Value", "Enrichment"])
168        self.annotationsChartView.setAlternatingRowColors(True)
169        self.annotationsChartView.setSortingEnabled(True)
170        self.annotationsChartView.setSelectionMode(QAbstractItemView.ExtendedSelection)
171        self.annotationsChartView.setRootIsDecorated(False)
172        self.annotationsChartView.viewport().setMouseTracking(True)
173#        self.annotationsChartView.viewport().setAttribute(Qt.WA_Hover)
174        self.mainArea.layout().addWidget(self.annotationsChartView)
[1761]175
[1478]176        contextEventFilter = OWGUI.VisibleHeaderSectionContextEventFilter(self.annotationsChartView)
177        self.annotationsChartView.header().installEventFilter(contextEventFilter)
[1761]178
[1478]179        self.taxid_list = []
[1761]180
[1478]181        self.connect(self.groupsWidget, SIGNAL("itemClicked(QTreeWidgetItem *, int)"), self.subsetSelectionChanged)
[1761]182
[1478]183        OWGUI.button(self.controlArea, self, "Commit", callback=self.commit)
[1761]184
[1478]185        self.loadedGenematcher = "None"
186        self.referenceData = None
187        self.data = None
[1761]188
[1478]189        self.treeItems = []
[1761]190
[1478]191        self.resize(1024, 600)
[1761]192
[1478]193        self.connect(self, SIGNAL("widgetStateChanged(QString, int, QString)"), self.onStateChange)
[1761]194
[1498]195        self.updatingAnnotationsFlag = False
[1761]196
[1478]197    def updateHierarchy(self):
198        try:
199            self.progressBarInit()
200            with orngServerFiles.DownloadProgress.setredirect(self.progressBarSet):
201                all, local = obiGeneSets.list_all(), obiGeneSets.list_local()
202                organisms = set(obiTaxonomy.essential_taxids() + [t[1] for t in all])
203            self.progressBarFinished()
[1761]204
[1574]205            organism_names = map(name_or_none, organisms)
206            organisms = [taxid for taxid, name in zip(organisms, organism_names) \
207                         if name is not None]
[1761]208
[1478]209            self.taxid_list = list(organisms)
210            self.speciesComboBox.clear()
211            self.speciesComboBox.addItems([obiTaxonomy.name(id) for id in self.taxid_list])
212            self.genesets = all
213        finally:
[1748]214            if self.signalManager:
[1761]215                self.signalManager.freeze(self).pop() #setFreeze(self.signalManager.freezing - 1)
216
[1478]217    def setData(self, data=None):
218        self.data = data
219        self.error(0)
220        self.closeContext("")
221        self.geneAttrComboBox.clear()
222        self.groupsWidget.clear()
223        self.annotationsChartView.clear()
[1761]224
[1478]225        if not getattr(self,"taxid_list", None):
226            QTimer.singleShot(100, lambda data=data: self.setData(data))
[1761]227            return
[1478]228        if data:
229            self.geneAttrs = [attr for attr in data.domain.variables + data.domain.getmetas().values() \
230                              if attr.varType != orange.VarTypes.Continuous]
[1761]231
[1478]232            self.geneAttrComboBox.addItems([attr.name for attr in self.geneAttrs])
233            self.geneattr = min(self.geneattr, len(self.geneAttrs) - 1)
[1761]234
[1478]235            taxid = data_hints.get_hint(data, "taxid", "")
236            try:
237                self.speciesIndex = self.taxid_list.index(taxid)
238            except ValueError, ex:
239                pass
240            self.genesinrows = data_hints.get_hint(data, "genesinrows", self.genesinrows)
[1761]241
[1478]242            self.openContext("", data)
[1761]243
[1478]244#            print self.speciesIndex
[1761]245
[1478]246            self.setHierarchy(self.getHierarchy(taxid=self.taxid_list[self.speciesIndex]))
[1761]247
[1478]248            self.loadedGenematcher = "None"
249            self.updateAnnotations()
[1761]250
[1478]251    def setReference(self, data=None):
252        self.referenceData = data
253        self.referenceRadioBox.setEnabled(bool(data))
[1761]254
[1478]255    def getHierarchy(self, taxid):
256        def recursive_dict():
257            return defaultdict(recursive_dict)
258        collection = recursive_dict()
[1761]259
[1478]260        def collect(col, hier):
261            if hier:
262                collect(col[hier[0]], hier[1:])
[1761]263
[1478]264        for hierarchy, t_id, _ in self.genesets:
265            collect(collection[t_id], hierarchy)
266        return collection[taxid]
[1761]267
[1478]268    def setHierarchy(self, hierarchy):
269        self.groupsWidgetItems = {}
270        def fill(col, parent, full=()):
271            for key, value in sorted(col.items()):
272                full_cat = full + (key,)
273                item = QTreeWidgetItem(parent, [key])
274                item.setFlags(item.flags() | Qt.ItemIsUserCheckable | Qt.ItemIsSelectable | Qt.ItemIsEnabled)
275                if value:
276                    item.setFlags(item.flags() | Qt.ItemIsTristate)
[1761]277
[1478]278                item.setData(0, Qt.CheckStateRole, QVariant(self.categoriesCheckState.get(full_cat, Qt.Checked)))
279                item.setExpanded(True)
280                item.category = full_cat
281                self.groupsWidgetItems[full_cat] = item
282                fill(value, item, full_cat)
[1761]283
[1478]284        fill(hierarchy, self.groupsWidget)
[1761]285
[1478]286#    def updateCategoryCounts(self):
287#        for cat, item in self.groupWidgetItem:
288#            item.setData(1, QVariant(), Qt.DisplayRole)
[1761]289
[1478]290    def selectedCategories(self):
291        taxid = self.taxid_list[self.speciesIndex]
292        return [(key, taxid) for key, check in self.getHierarchyCheckState().items() if check == Qt.Checked]
293
294    def getHierarchyCheckState(self):
295        def collect(item, full=()):
296            checked = item.checkState(0)
297            name = str(item.data(0, Qt.DisplayRole).toString())
298            full_cat = full + (name,)
299            result = [(full_cat, checked)]
300            for i in range(item.childCount()):
301                result.extend(collect(item.child(i), full_cat))
302            return result
[1761]303
[1478]304        items = [self.groupsWidget.topLevelItem(i) for i in range(self.groupsWidget.topLevelItemCount())]
305        states = reduce(list.__add__, [collect(item) for item in items], [])
306        return dict(states)
[1761]307
[1478]308    def subsetSelectionChanged(self, item, column):
309        self.categoriesCheckState = self.getHierarchyCheckState()
[1761]310
[1478]311        categories = self.selectedCategories()
312        if not set(categories) <= set(self.currentAnnotatedCategories):
313            self.updateAnnotations()
314        else:
315            self.filterAnnotationsChartView()
[1761]316
[1478]317    def updateGeneMatcherSettings(self):
[1632]318        from .OWGOEnrichmentAnalysis import GeneMatcherDialog
[1478]319        dialog = GeneMatcherDialog(self, defaults=self.geneMatcherSettings, enabled=[True] * 4, modal=True)
320        if dialog.exec_():
321            self.geneMatcherSettings = [getattr(dialog, item[0]) for item in dialog.items]
322            self.loadedGenematcher = "None"
323            if self.data:
324                self.updateAnnotations()
[1761]325
[1478]326    def updateGenematcher(self):
327        taxid = self.taxid_list[self.speciesIndex]
328        if taxid != self.loadedGenematcher:
329            self.progressBarInit()
330            call = self.asyncCall(obiGene.matcher, name="Gene Matcher", blocking=True, thread=self.thread())
331            call.connect(call, SIGNAL("progressChanged(float)"), self.progressBarSet)
332            with orngServerFiles.DownloadProgress.setredirect(call.emitProgressChanged):
333#            with orngServerFiles.DownloadProgress.setredirect(self.progressBarSet):
334                matchers = [obiGene.GMGO, obiGene.GMKEGG, obiGene.GMNCBI, obiGene.GMAffy]
335                if any(self.geneMatcherSettings):
336                    call.__call__([gm(taxid) for gm, use in zip(matchers, self.geneMatcherSettings) if use])
337                    self.genematcher = call.get_result()
338#                    self.genematcher = obiGene.matcher([gm(taxid) for gm, use in zip(matchers, self.geneMatcherSettings) if use])
339                else:
340                    self.genematcher = obiGene.GMDirect()
341#                self.genematcher.set_targets(self.referenceGenes())
342                self.loadedGenematcher = taxid
343            self.progressBarFinished()
[1761]344
[1478]345    def genesFromExampleTable(self, table):
346        if self.genesinrows:
347            genes = [attr.name for attr in table.domain.attributes]
348        else:
349            geneattr = self.geneAttrs[self.geneattr]
350            genes = [str(ex[geneattr]) for ex in table]
351        return genes
[1761]352
[1478]353    def clusterGenes(self):
354        return self.genesFromExampleTable(self.data)
[1761]355
[1478]356    def referenceGenes(self):
357        if self.referenceData and self.useReferenceData:
358            return self.genesFromExampleTable(self.referenceData)
359        else:
360            taxid = self.taxid_list[self.speciesIndex]
361            call = self.asyncCall(obiGene.NCBIGeneInfo, (taxid,), name="Load reference genes", blocking=True, thread=self.thread())
362            call.connect(call, SIGNAL("progressChanged(float)"), self.progressBarSet)
363            with orngServerFiles.DownloadProgress.setredirect(call.emitProgressChanged):
364                call.__call__()
365                return call.get_result()
[1761]366
[1478]367    def _cached_name_lookup(self, func, cache):
368        def f(name, cache=cache):
369            if name not in cache:
370                cache[name] = func(name)
371            return cache[name]
372        return f
[1761]373
[1478]374    def mapGeneNames(self, names, cache=None, passUnknown=False):
375        if cache is not None:
376            umatch = self._cached_name_lookup(self.genematcher.umatch, cache)
377        else:
378            umatch = self.genematcher.umatch
379        if passUnknown:
380            return [umatch(name) or name for name in names]
381#            return [(mapped_name or name, mapped_name is not None) for mapped_name, name in zip(mapped, names)]
382        return [n for n in [umatch(name) for name in names] if n is not None]
[1761]383
[1478]384    def enrichment(self, geneset, cluster, reference, pval=obiProb.Hypergeometric(), cache=None):
385        genes = set(self.mapGeneNames(geneset.genes, cache, passUnknown=False))
[1761]386
[1478]387        cmapped = genes.intersection(cluster)
388        rmapped = genes.intersection(reference)
389        return (cmapped, rmapped, pval.p_value(len(cmapped), len(reference), len(rmapped), len(cluster)), float(len(cmapped)) / (len(cluster) or 1) / (float(len(rmapped) or 1) / (len(reference) or 1))) # TODO: compute all statistics here
[1761]390
[1478]391    def updateAnnotations(self):
392        self.updatingAnnotationsFlag = True
393        self.annotationsChartView.clear()
394        self.error([0, 1])
395        if not self.genesinrows and len(self.geneAttrs) == 0:
396            self.error(0, "Input data contains no attributes with gene names")
397            return
[1761]398
[1478]399        self.progressBarInit()
400        self.updateGenematcher()
401        self.currentAnnotatedCategories = categories = self.selectedCategories()
[1761]402
[1478]403        ## Load collections in a worker thread
404        call = self.asyncCall(obiGeneSets.collections, categories, name="Loading collections", blocking=True, thread=self.thread())
405        call.connect(call, SIGNAL("progressChanged(float)"), self.progressBarSet)
406        with orngServerFiles.DownloadProgress.setredirect(call.emitProgressChanged):
407            call.__call__()
408            collections = list(call.get_result())
[1761]409
[1478]410#        with orngServerFiles.DownloadProgress.setredirect(self.progressBarSet):
[1761]411#            collections = list(obiGeneSets.collections(*categories))
[1478]412        clusterGenes, referenceGenes = self.clusterGenes(), self.referenceGenes()
413        cache = {}
414
415        self.genematcher.set_targets(referenceGenes)
[1761]416
[1478]417        countAll = len(set(clusterGenes))
418        infoText = "%i unique gene names on input\n" % countAll
419        referenceGenes = set(self.mapGeneNames(referenceGenes, cache, passUnknown=False))
420        self.progressBarSet(1)
421        clusterGenes = set(self.mapGeneNames(clusterGenes, cache, passUnknown=False))
422        self.progressBarSet(2)
423        infoText += "%i (%.1f) gene names matched" % (len(clusterGenes), 100.0 * len(clusterGenes) / countAll)
424        self.infoBox.setText(infoText)
[1761]425
[1478]426        results = []
[1632]427        from Orange.orng.orngMisc import progressBarMilestones
[1761]428
[1478]429        milestones = progressBarMilestones(len(collections), 100)
430        for i, geneset in enumerate(collections):
431            results.append((geneset, self.enrichment(geneset, clusterGenes, referenceGenes, cache=cache)))
432            if i in milestones:
433                self.progressBarSet(100.0 * i / len(collections))
[1761]434
[1478]435        if self.useFDR:
436            results = sorted(results, key=lambda a:a[1][2])
437            pvals = obiProb.FDR([pval for _, (_, _, pval, _) in results])
438            results = [(geneset, (cmapped, rmapped, pvals[i], es)) for i, (geneset, (cmapped, rmapped, _, es)) in enumerate(results)]
[1761]439
[1478]440        fmt = lambda score, max_decimals=10: "%%.%if" % min(int(abs(math.log(max(score, 1e-10)))) + 2, max_decimals) if score > math.pow(10, -max_decimals) and score < 1 else "%.1f"
441        self.annotationsChartView.clear()
[1761]442
[1478]443        maxCount = max([len(cm) for _, (cm, _, _, _) in results] + [1])
444        maxRefCount = max([len(rc) for _, (_, rc, _, _) in results] + [1])
445        countSpaces = int(math.ceil(math.log10(maxCount)))
[1761]446        #print maxRefCount
[1478]447        refSpaces = int(math.ceil(math.log(maxRefCount)))
448        countFmt = "%"+str(countSpaces) + "s  (%.2f%%)"
449        refFmt = "%"+str(refSpaces) + "s  (%.2f%%)"
[1761]450
[1478]451        self.filterCompleter.setModel(None)
452        linkFont = QFont(self.annotationsChartView.viewOptions().font)
453        linkFont.setUnderline(True)
454        self.treeItems = []
455        for i, (geneset, (cmapped, rmapped, p_val, enrichment)) in enumerate(results):
456            if len(cmapped) > 0:
[1498]457                item = MyTreeWidgetItem(self.annotationsChartView, [" ".join(geneset.hierarchy), geneset.name])
[1478]458                item.setData(2, Qt.DisplayRole, QVariant(countFmt % (len(cmapped), 100.0*len(cmapped)/countAll)))
[1498]459                item.setData(2, Qt.ToolTipRole, QVariant(len(cmapped))) # For filtering
[1478]460                item.setData(3, Qt.DisplayRole, QVariant(refFmt % (len(rmapped), 100.0*len(rmapped)/len(referenceGenes))))
[1761]461                item.setData(4, Qt.DisplayRole, QVariant("%0.2e"% p_val))
462                item.setData(4, 42, QVariant(p_val))
463                #stoplec 4 - zelim sort po p_val
464                item.setData(4, Qt.ToolTipRole, QVariant("%0.10f" % p_val))
[1478]465                item.setData(5, Qt.DisplayRole, QVariant(enrichment))
466                item.setData(5, Qt.ToolTipRole, QVariant("%.3f" % enrichment))
467                item.geneset= geneset
468                self.treeItems.append(item)
469                if geneset.link:
470                    item.setData(1, LinkRole, QVariant(geneset.link))
471                    item.setToolTip(1, geneset.link)
472                    item.setFont(1, linkFont)
473                    item.setForeground(1, QColor(Qt.blue))
[1761]474
[1478]475        if not self.treeItems:
476            self.warning(0, "No enriched sets found.")
477        else:
478            self.warning(0)
[1761]479
[1478]480        replace = lambda s:s.replace(",", " ").replace("(", " ").replace(")", " ")
481        self._completerModel = completerModel = QStringListModel(sorted(reduce(set.union, [[geneset.name] + replace(geneset.name).split() for geneset, (c, _, _, _) in results if c], set())))
482        self.filterCompleter.setModel(completerModel)
[1761]483
[1478]484        self.annotationsChartView.setItemDelegateForColumn(5, BarItemDelegate(self, scale=(0.0, max(t[1][3] for t in results))))
485        self.annotationsChartView.setItemDelegateForColumn(1, LinkStyledItemDelegate(self.annotationsChartView))
[1761]486
[1478]487        for i in range(self.annotationsChartView.columnCount()):
488            self.annotationsChartView.resizeColumnToContents(i)
[1761]489
[1478]490        self.annotationsChartView.setColumnWidth(1, min(self.annotationsChartView.columnWidth(1), 300))
491        self.progressBarFinished()
492        QTimer.singleShot(10, self.filterAnnotationsChartView)
493        self.updatingAnnotationsFlag = False
[1761]494
[1478]495    def filterAnnotationsChartView(self, filterString=""):
496        if self.updatingAnnotationsFlag:
497            return
498        categories = set(" ".join(cat) for cat, taxid in self.selectedCategories())
499        filterString = str(self.filterLineEdit.text()).lower()
500        itemsHidden = []
501        for item in self.treeItems:
502            item_cat = str(item.data(0, Qt.EditRole).toString())
[1761]503            count, pval = _toPyObject(item.data(2, Qt.ToolTipRole)), _toPyObject(item.data(4, 42))
[1478]504            geneset = item.geneset.name.lower()
505            hidden = item_cat not in categories or (self.useMinCountFilter and count < self.minClusterCount) or \
506                     (self.useMaxPValFilter and pval > self.maxPValue) or filterString not in geneset
507            item.setHidden(hidden)
508            itemsHidden.append(hidden)
[1761]509
[1478]510        if self.treeItems and all(itemsHidden):
511            self.information(0, "All sets were filtered out.")
512        else:
513            self.information(0)
[1761]514
515
[1478]516    def commit(self):
517        selected = self.annotationsChartView.selectedItems()
518        genesets = [item.geneset for item in selected]
519        cache = {}
520        mappedNames = set(self.mapGeneNames(reduce(set.union, [geneset.genes for geneset in genesets], set()), cache))
521        if self.genesinrows:
522            mapped = [attr for attr in self.data.domain.attributes if self.genematcher.umatch(attr.name) in mappedNames]
523            newdomain = orange.Domain(mapped, self.data.domain.classVar)
524            newdomain.addmetas(self.data.domain.getmetas())
525            data = orange.ExampleTable(newdomain, self.data)
526        else:
527            geneattr = self.geneAttrs[self.geneattr]
[1761]528            selected = [1 if self.genematcher.umatch(str(ex[geneattr])) in mappedNames else 0 for ex in self.data]
[1478]529            data = self.data.select(selected)
[1761]530
[1478]531#            if self.appendAnnotations:
532#                meta = orange.StringVariable("Annotations")
533#                data.domain.addmeta(orange.newmetaid(), meta)
534#                for ex in data:
535#                    geneattr = self.geneAttrs[self.geneattr]
536#                    gene = str(ex[geneattr])
537#                    annotations = getgene
[1761]538
[1478]539        self.send("Selected Examples", data)
[1761]540
[1478]541    def sendReport(self):
542        self.reportSettings("Settings", [("Organism", obiTaxonomy.name(self.taxid_list[self.speciesIndex]))])
543        self.reportSettings("Filter", [("Min cluster size", self.minClusterCount if self.useMinCountFilter else 0),
544                                       ("Max p-value", self.maxPValue if self.useMaxPValFilter else 1.0)])
[1761]545
[1478]546        self.reportSubsection("Annotations")
547        self.reportRaw(reportItemView(self.annotationsChartView))
[1761]548
[1478]549    def onStateChange(self, stateType, id, text):
550        if stateType == "Warning" or stateType == "Info":
551            self.annotationsChartView._userMessage = text
552            self.annotationsChartView.viewport().update()
[1761]553
554
[1478]555def reportItemView(view):
556    model = view.model()
557    return reportItemModel(view, model)
[1761]558
[1478]559def reportItemModel(view, model, index=QModelIndex()):
560    if not index.isValid() or model.hasChildren(index):
561        columnCount, rowCount = model.columnCount(index), model.rowCount(index)
562        if not index.isValid():
563            text = '<table>\n<tr>' + ''.join('<th>%s</th>' % model.headerData(i, Qt.Horizontal, Qt.DisplayRole).toString() for i in range(columnCount)) +'</tr>\n'
564        else:
565#            variant = model.data(index, Qt.DisplayRole)
566#            text = '<table' + (' caption="%s"' % variant.toString() if variant.isValid() else '') + '>\n'
567            pass
568        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))
569        text += '</table>'
570        return text
571    else:
572        variant = model.data(index, Qt.DisplayRole)
573        return str(variant.toString()) if variant.isValid() else ""
574
[1761]575
576
[1478]577if __name__ == "__main__":
578    import cProfile
[1761]579
[1478]580    app = QApplication(sys.argv)
581    w = OWSetEnrichment()
582    w.updateHierarchy()
[1761]583    data = orange.ExampleTable("yeast-class-RPR.tab")
[1478]584#    data = orange.ExampleTable("../human")
585#    print cProfile.runctx("w.setData(data)", globals(), locals())
586    w.setData(data)
587    w.show()
588    app.exec_()
589    w.saveSettings()
[1761]590
591
Note: See TracBrowser for help on using the repository browser.