source: orange-bioinformatics/Orange/bioinformatics/widgets/OWSetEnrichment.py @ 1625:cefeb35cbfc9

Revision 1625:cefeb35cbfc9, 26.7 KB checked in by mitar, 2 years ago (diff)

Moving files around.

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