source: orange-bioinformatics/orangecontrib/bio/widgets/OWSetEnrichment.py @ 1874:b3e32cc5cf6f

Revision 1874:b3e32cc5cf6f, 27.0 KB checked in by Ales Erjavec <ales.erjavec@…>, 7 months ago (diff)

Added new style widget meta descriptions.

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