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

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

Added new style widget meta descriptions.

RevLine 
[188]1"""
[1462]2<name>GO Browser</name>
[764]3<description>Enrichment analysis for Gene Ontology terms.</description>
[188]4<contact>Ales Erjavec</contact>
[1726]5<icon>icons/GOBrowser.svg</icon>
[1052]6<priority>2020</priority>
[188]7"""
8
[1632]9from __future__ import absolute_import, with_statement
[857]10
[188]11from collections import defaultdict
[638]12from functools import partial
[1632]13import gc
14import sys, os, tarfile, math
15from os.path import join as p_join
[188]16
[1632]17from Orange.orng import orngServerFiles
18from Orange.orng.orngDataCaching import data_hints
19from Orange.OrangeWidgets import OWGUI
20from Orange.OrangeWidgets.OWWidget import *
21
22from .. import obiGene, obiGO, obiProb, obiTaxonomy
[1118]23
[1874]24NAME = "GO Browser"
25DESCRIPTION = "Enrichment analysis for Gene Ontology terms."
26ICON = "icons/GOBrowser.svg"
27PRIORITY = 2020
28
29INPUTS = [("Cluster Examples", Orange.data.Table,
30           "SetClusterDataset", Single + Default),
31          ("Reference Examples", Orange.data.Table,
32           "SetReferenceDataset")]
33
34OUTPUTS = [("Selected Examples", Orange.data.Table),
35           ("Unselected Examples", Orange.data.Table),
36           ("Example With Unknown Genes", Orange.data.Table),
37           ("Enrichment Report", Orange.data.Table)]
38
39REPLACES = ["_bioinformatics.widgets.OWGOEnrichmentAnalysis.OWGOEnrichmentAnalysis"]
40
41
[638]42dataDir = orngServerFiles.localpath("GO")
[511]43
[811]44def listAvailable():
[540]45    files = orngServerFiles.listfiles("GO")
46    ret = {}
47    for file in files:
48        tags = orngServerFiles.info("GO", file)["tags"]
49        td = dict([tuple(tag.split(":")) for tag in tags if tag.startswith("#") and ":" in tag])
[545]50        if "association" in file.lower():
51            ret[td.get("#organism", file)] = file
[811]52    orgMap = {"352472":"44689"}
[988]53    essential = ["gene_association.%s.tar.gz" % obiGO.from_taxid(id) for id in obiTaxonomy.essential_taxids() if obiGO.from_taxid(id)]
[985]54    essentialNames = [obiTaxonomy.name(id) for id in obiTaxonomy.essential_taxids() if obiGO.from_taxid(id)]
[811]55    ret.update(zip(essentialNames, essential))
[540]56    return ret
[511]57
[964]58class _disablegc(object):
59    def __enter__(self):
60        gc.disable()
61    def __exit__(self, *args):
62        gc.enable()
63
[511]64def getOrgFileName(org):
[1632]65    from Orange.orng import orngServerFiles
[511]66    files = orngServerFiles.listfiles("go")
67    return [f for f in files if org in f].pop()
68
[188]69class TreeNode(object):
70    def __init__(self, tuple, children):
71        self.tuple = tuple
72        self.children = children
[638]73
74class GOTreeWidget(QTreeWidget):
75    def contextMenuEvent(self, event):
76        QTreeWidget.contextMenuEvent(self, event)
[646]77##        print event.x(), event.y()
[638]78        term = self.itemAt(event.pos()).term
79        self._currMenu = QMenu()
80        self._currAction = self._currMenu.addAction("View term on AmiGO website")
81##        self.connect(self, SIGNAL("triggered(QAction*)"), partial(self.BrowserAction, term))
82        self.connect(self._currAction, SIGNAL("triggered()"), lambda :self.BrowserAction(term))
83        self._currMenu.popup(event.globalPos())
84
85    def BrowserAction(self, term):
86        import webbrowser
[1340]87        if isinstance(term, obiGO.Term):
88            term = term.id
[638]89        webbrowser.open("http://amigo.geneontology.org/cgi-bin/amigo/term-details.cgi?term="+term)
[1248]90       
91    def paintEvent(self, event):
92        QTreeWidget.paintEvent(self, event)
93        if getattr(self, "_userMessage", None):
94            painter = QPainter(self.viewport())
95            font = QFont(self.font())
96            font.setPointSize(15)
97            painter.setFont(font)
98            painter.drawText(self.viewport().geometry(), Qt.AlignCenter, self._userMessage)
99            painter.end()
[638]100
[1710]101
[188]102class OWGOEnrichmentAnalysis(OWWidget):
[1710]103    settingsList = ["annotationIndex", "useReferenceDataset", "aspectIndex",
104                    "geneAttrIndex", "geneMatcherSettings",
105                    "filterByNumOfInstances", "minNumOfInstances",
106                    "filterByPValue", "maxPValue", "selectionDirectAnnotation",
107                    "selectionDisjoint", "selectionType",
108                    "selectionAddTermAsClass", "useAttrNames", "probFunc",
109                    "useFDR"
110                    ]
111
112    contextHandlers = {"": DomainContextHandler(
113                                "",
114                                ["geneAttrIndex", "useAttrNames",
115                                 "annotationIndex", "geneMatcherSettings"],
116                                matchValues=1)
117                       }
118
[1462]119    def __init__(self, parent=None, signalManager=None, name="GO Browser"):
[188]120        OWWidget.__init__(self, parent, signalManager, name)
[1710]121        self.inputs = [("Cluster Examples", ExampleTable,
122                        self.SetClusterDataset, Default),
123                       ("Reference Examples", ExampleTable,
124                        self.SetReferenceDataset, Single + NonDefault)]
125
126        self.outputs = [("Selected Examples", ExampleTable, Default),
127                        ("Unselected Examples", ExampleTable, Default),
128                        ("Example With Unknown Genes", ExampleTable, Default),
129                        ("Enrichment Report", ExampleTable)]
[188]130
131        self.annotationIndex = 0
132        self.autoFindBestOrg = False
[1710]133        self.useReferenceDataset = 0
[188]134        self.aspectIndex = 0
135        self.geneAttrIndex = 0
136        self.useAttrNames = False
[988]137        self.geneMatcherSettings = [True, False, False, False]
[188]138        self.filterByNumOfInstances = False
139        self.minNumOfInstances = 1
140        self.filterByPValue = True
141        self.maxPValue = 0.1
[801]142        self.probFunc = 0
143        self.useFDR = True
[188]144        self.selectionDirectAnnotation = 0
145        self.selectionDisjoint = 0
146        self.selectionAddTermAsClass = 0
[219]147        self.selectionChanging = 0
148       
[188]149        # check usage of all evidences
[540]150        for etype in obiGO.evidenceTypesOrdered:
[1328]151            varName = "useEvidence" + etype
152            if varName not in self.settingsList: 
153                self.settingsList.append(varName)
[188]154            code = compile("self.%s = True" % (varName), ".", "single")
155            exec(code)
[865]156        self.annotationCodes = []
157       
[1328]158        self.loadSettings()
159       
[188]160        #############
161        ##GUI
162        #############
[196]163        self.tabs = OWGUI.tabWidget(self.controlArea)
[188]164        ##Input tab
[196]165        self.inputTab = OWGUI.createTabPage(self.tabs, "Input")
[770]166        box = OWGUI.widgetBox(self.inputTab, "Info")
167        self.infoLabel = OWGUI.widgetLabel(box, "No data on input\n")
[1248]168       
[1328]169        OWGUI.button(box, self, "Ontology/Annotation Info", callback=self.ShowInfo,
170                     tooltip="Show information on loaded ontology and annotations",
171                     debuggingEnabled=0)
[770]172        box = OWGUI.widgetBox(self.inputTab, "Organism", addSpace=True)
[1328]173        self.annotationComboBox = OWGUI.comboBox(box, self, "annotationIndex",
174                            items = self.annotationCodes, callback=self.Update,
175                            tooltip="Select organism", debuggingEnabled=0)
[865]176       
[1328]177        # freeze until annotation combo box is updateded with available annotations.
[1748]178        if self.signalManager:
179            self.signalManager.freeze(self).push()
[865]180        QTimer.singleShot(0, self.UpdateOrganismComboBox)
181       
[1328]182        self.geneAttrIndexCombo = OWGUI.comboBox(self.inputTab, self, "geneAttrIndex",
183                            box="Gene names", callback=self.Update,
184                            tooltip="Use this attribute to extract gene names from input data")
185        OWGUI.checkBox(self.geneAttrIndexCombo.box, self, "useAttrNames", "Use data attributes names",
186                       disables=[(-1, self.geneAttrIndexCombo)], callback=self.Update, 
187                       tooltip="Use attribute names for gene names")
188        OWGUI.button(self.geneAttrIndexCombo.box, self, "Gene matcher settings", 
189                     callback=self.UpdateGeneMatcher, 
190                     tooltip="Open gene matching settings dialog", 
191                     debuggingEnabled=0)
[801]192       
[1328]193        self.referenceRadioBox = OWGUI.radioButtonsInBox(self.inputTab, self, "useReferenceDataset", 
194                                                         ["Entire genome", "Reference set (input)"],
195                                                         tooltips=["Use entire genome for reference",
196                                                                   "Use genes from Referece Examples input signal as reference"],
197                                                         box="Reference", callback=self.Update)
[770]198        self.referenceRadioBox.buttons[1].setDisabled(True)
[1328]199        OWGUI.radioButtonsInBox(self.inputTab, self, "aspectIndex", ["Biological process",
200                                                                     "Cellular component",
201                                                                     "Molecular function"], 
202                                box="Aspect", callback=self.Update)
203       
[215]204        self.geneAttrIndexCombo.setDisabled(bool(self.useAttrNames))
[188]205       
206        ##Filter tab
[196]207        self.filterTab = OWGUI.createTabPage(self.tabs, "Filter")
[188]208        box = OWGUI.widgetBox(self.filterTab, "Filter GO Term Nodes", addSpace=True)
[1328]209        OWGUI.checkBox(box, self, "filterByNumOfInstances", "Genes",
210                       callback=self.FilterAndDisplayGraph, 
211                       tooltip="Filter by number of input genes mapped to a term")
212        OWGUI.spin(OWGUI.indentedBox(box), self, 'minNumOfInstances', 1, 100, 
213                   step=1, label='#:', labelWidth=15, 
214                   callback=self.FilterAndDisplayGraph, 
215                   callbackOnReturn=True, 
216                   tooltip="Min. number of input genes mapped to a term")
217       
218        OWGUI.checkBox(box, self, "filterByPValue", "Significance",
219                       callback=self.FilterAndDisplayGraph, 
220                       tooltip="Filter by term p-value")
221        OWGUI.doubleSpin(OWGUI.indentedBox(box), self, 'maxPValue', 1e-8, 1, 
222                         step=1e-8,  label='p:', labelWidth=15, 
223                         callback=self.FilterAndDisplayGraph, 
224                         callbackOnReturn=True, 
225                         tooltip="Max term p-value")
[801]226        box = OWGUI.widgetBox(box, "Significance test")
[1328]227        OWGUI.radioButtonsInBox(box, self, "probFunc", ["Binomial", "Hypergeometric"], 
228                                tooltips=["Use binomial distribution test", 
229                                          "Use hypergeometric distribution test"], 
230                                callback=self.Update)
231        OWGUI.checkBox(box, self, "useFDR", "Use FDR (False Discovery Rate)", 
232                       callback=self.Update, 
233                       tooltip="Use False Discovery Rate correction")
234        box = OWGUI.widgetBox(self.filterTab, "Evidence codes in annotation", 
235                              addSpace=True)
[188]236        self.evidenceCheckBoxDict = {}
[540]237        for etype in obiGO.evidenceTypesOrdered:
[1328]238            self.evidenceCheckBoxDict[etype] = OWGUI.checkBox(box, self, "useEvidence"+etype, etype,
239                                            callback=self.Update, tooltip=obiGO.evidenceTypes[etype])
[188]240       
241        ##Select tab
[196]242        self.selectTab = OWGUI.createTabPage(self.tabs, "Select")
[1328]243        box = OWGUI.radioButtonsInBox(self.selectTab, self, "selectionDirectAnnotation", 
244                                      ["Directly or Indirectly", "Directly"], 
245                                      box="Annotated genes", 
246                                      callback=self.ExampleSelection)
247       
[188]248        box = OWGUI.widgetBox(self.selectTab, "Output", addSpace=True)
[1328]249        OWGUI.radioButtonsInBox(box, self, "selectionDisjoint", 
250                                btnLabels=["All selected genes", 
251                                           "Term-specific genes", 
252                                           "Common term genes"], 
253                                tooltips=["Outputs genes annotated to all selected GO terms", 
254                                          "Outputs genes that appear in only one of selected GO terms", 
255                                          "Outputs genes common to all selected GO terms"], 
256                                callback=[self.ExampleSelection,
257                                          self.UpdateAddClassButton])
258        self.addClassCB = OWGUI.checkBox(box, self, "selectionAddTermAsClass",
259                                         "Add GO Term as class", 
260                                         callback=self.ExampleSelection)
[188]261
262        # ListView for DAG, and table for significant GOIDs
[851]263        self.DAGcolumns = ['GO term', 'Cluster', 'Reference', 'p value', 'Genes', 'Enrichment']
[1328]264       
[196]265        self.splitter = QSplitter(Qt.Vertical, self.mainArea)
266        self.mainArea.layout().addWidget(self.splitter)
[188]267
268        # list view
[638]269        self.listView = GOTreeWidget(self.splitter)
[843]270        self.listView.setSelectionMode(QAbstractItemView.ExtendedSelection)
[188]271        self.listView.setAllColumnsShowFocus(1)
[196]272        self.listView.setColumnCount(len(self.DAGcolumns))
273        self.listView.setHeaderLabels(self.DAGcolumns)
274       
[200]275        self.listView.header().setClickable(True)
276        self.listView.header().setSortIndicatorShown(True)
277        self.listView.setSortingEnabled(True)
[416]278        self.listView.setItemDelegateForColumn(5, EnrichmentColumnItemDelegate(self))
[641]279        self.listView.setRootIsDecorated(True)
280
[200]281       
[196]282        self.connect(self.listView, SIGNAL("itemSelectionChanged()"), self.ViewSelectionChanged)
[641]283       
[188]284        # table of significant GO terms
[511]285        self.sigTerms = QTreeWidget(self.splitter)
286        self.sigTerms.setColumnCount(len(self.DAGcolumns))
287        self.sigTerms.setHeaderLabels(self.DAGcolumns)
[641]288        self.sigTerms.setSortingEnabled(True)
[843]289        self.sigTerms.setSelectionMode(QAbstractItemView.ExtendedSelection)
[641]290       
[511]291        self.connect(self.sigTerms, SIGNAL("itemSelectionChanged()"), self.TableSelectionChanged)
[188]292        self.splitter.show()
293
294        self.sigTableTermsSorted = []
295        self.graph = {}
[854]296       
[188]297        self.loadedAnnotationCode = "---"
[196]298       
299        self.inputTab.layout().addStretch(1)
300        self.filterTab.layout().addStretch(1)
301        self.selectTab.layout().addStretch(1)
302       
[899]303        self.resize(1000, 800)
[188]304
305        self.clusterDataset = None
[854]306        self.referenceDataset = None
[540]307        self.ontology = None
308        self.annotations = None
[1139]309        self.treeStructRootKey = None
[801]310        self.probFunctions = [obiProb.Binomial(), obiProb.Hypergeometric()]
[1002]311        self.selectedTerms = []
[188]312       
[1248]313        self.connect(self, SIGNAL("widgetStateChanged(QString, int, QString)"), self.onStateChanged)
314       
[865]315    def UpdateOrganismComboBox(self):
316        try:
317            if self.annotationCodes and len(self.annotationCodes) > self.annotationIndex:
318                currAnnotationCode = self.annotationCodes[self.annotationIndex]
319            else:
320                currAnnotationCode = None
321            self.progressBarInit()
322            with orngServerFiles.DownloadProgress.setredirect(self.progressBarSet):
323                self.annotationFiles = listAvailable()
324            self.progressBarFinished()
325            self.annotationCodes = sorted(self.annotationFiles.keys())
326            self.annotationComboBox.clear()
327            self.annotationComboBox.addItems(self.annotationCodes)
328            self.annotationComboBox.setCurrentIndex(self.annotationIndex)
329        finally:
[1748]330            if self.signalManager:
331                self.signalManager.freeze(self).pop()
332
[988]333    def UpdateGeneMatcher(self):
334        dialog = GeneMatcherDialog(self, defaults=self.geneMatcherSettings, modal=True)
335        if dialog.exec_():
336            self.geneMatcherSettings = [getattr(dialog, item[0]) for item in dialog.items]
337            if self.annotations:
338                self.SetGeneMatcher()
339                if self.clusterDataset:
340                    self.Update()
341               
[188]342    def Update(self):
343        if self.clusterDataset:
[1014]344            pb = OWGUI.ProgressBar(self, 100)
345            self.Load(pb=pb)
[188]346            self.FilterUnknownGenes()
[1014]347            graph = self.Enrichment(pb=pb)
[188]348            self.SetGraph(graph)
349
[511]350    def UpdateGOAndAnnotation(self, tags=[]):
[1632]351        from .OWUpdateGenomicsDatabases import OWUpdateGenomicsDatabases
[511]352        w = OWUpdateGenomicsDatabases(parent = self, searchString=" ".join(tags))
[396]353        w.setModal(True)
[188]354        w.show()
[511]355        self.UpdateAnnotationComboBox()
[188]356
357    def UpdateAnnotationComboBox(self):
[396]358        if self.annotationCodes:
[540]359            curr = self.annotationCodes[min(self.annotationIndex, len(self.annotationCodes)-1)]
[396]360        else:
361            curr = None
[811]362        self.annotationFiles = listAvailable()
[540]363        self.annotationCodes = self.annotationFiles.keys()
[396]364        index = curr and self.annotationCodes.index(curr) or 0
[188]365        self.annotationComboBox.clear()
[396]366        self.annotationComboBox.addItems(self.annotationCodes)
367        self.annotationComboBox.setCurrentIndex(index)
368        if not self.annotationCodes:
369            self.error(0, "No downloaded annotations!!\nClick the update button and update annotationa for at least one organism!")
370        else:
371            self.error(0)
[188]372
373    def SetGenesComboBox(self):
[389]374        self.candidateGeneAttrs = self.clusterDataset.domain.variables + self.clusterDataset.domain.getmetas().values()
[1328]375        self.candidateGeneAttrs = filter(lambda v: v.varType in [orange.VarTypes.String,
376                                                                 orange.VarTypes.Other,
377                                                                 orange.VarTypes.Discrete], 
378                                         self.candidateGeneAttrs)
[188]379        self.geneAttrIndexCombo.clear()
[196]380        self.geneAttrIndexCombo.addItems([a.name for a in  self.candidateGeneAttrs])
[188]381
382    def FindBestGeneAttrAndOrganism(self):
383        if self.autoFindBestOrg: 
384            organismGenes = dict([(o,set(go.getCachedGeneNames(o))) for o in self.annotationCodes])
385        else:
[540]386            currCode = self.annotationCodes[min(self.annotationIndex, len(self.annotationCodes)-1)]
387            filename = p_join(dataDir, self.annotationFiles[currCode])
[638]388            try:
389                f = tarfile.open(filename)
390                info = [info for info in f.getmembers() if info.name.startswith("gene_names")].pop()
391                geneNames = cPickle.loads(f.extractfile(info).read().replace("\r\n", "\n"))
392            except Exception, ex:
393                geneNames = cPickle.loads(open(p_join(filename, "gene_names.pickle")).read().replace("\r\n", "\n"))
[511]394            organismGenes = {currCode: set(geneNames)}
[188]395        candidateGeneAttrs = self.clusterDataset.domain.attributes + self.clusterDataset.domain.getmetas().values()
[1328]396        candidateGeneAttrs = filter(lambda v: v.varType in [orange.VarTypes.String, 
397                                                            orange.VarTypes.Other, 
398                                                            orange.VarTypes.Discrete], 
399                                    candidateGeneAttrs)
[188]400        attrNames = [v.name for v in self.clusterDataset.domain.variables]
401        cn = {}
402        for attr in candidateGeneAttrs:
403            vals = [str(e[attr]) for e in self.clusterDataset]
[209]404            if any("," in val for val in vals):
405                vals = reduce(list.__add__, (val.split(",") for val in vals))
[188]406            for organism, s in organismGenes.items():
407                l = filter(lambda a: a in s, vals)
[540]408                cn[(attr,organism)] = len(set(l))
[188]409        for organism, s in organismGenes.items():
410            l = filter(lambda a: a in s, attrNames)
[540]411            cn[("_var_names_", organism)] = len(set(l))
[188]412           
413        cn = cn.items()
414        cn.sort(lambda a,b:-cmp(a[1],b[1]))
[390]415        ((bestAttr, organism), count) = cn[0]
416        if bestAttr=="_var_names_" and count<=len(attrNames)/10.0 or \
417           bestAttr!="_var_names_" and count<=len(self.clusterDataset)/10.0:
418            return
419       
420        self.annotationIndex = self.annotationCodes.index(organism)
[188]421        if bestAttr=="_var_names_":
422            self.useAttrNames = True
423            self.geneAttrIndex = 0
424        else:
425            self.useAttrNames = False
426            self.geneAttrIndex = candidateGeneAttrs.index(bestAttr)
[1710]427
[188]428    def SetClusterDataset(self, data=None):
[1254]429        if not self.annotationCodes:
430            QTimer.singleShot(200, lambda: self.SetClusterDataset(data))
431            return
[416]432        self.closeContext()
[188]433        self.clusterDataset = data
[770]434        self.infoLabel.setText("\n")
[188]435        if data:
436            self.SetGenesComboBox()
[1118]437            try:
438                taxid = data_hints.get_hint(data, "taxid", "")
439                code = obiGO.from_taxid(taxid)
440                filename = "gene_association.%s.tar.gz" % code
441                if filename in self.annotationFiles.values():
[1710]442                    self.annotationIndex = \
443                            [i for i, name in enumerate(self.annotationCodes) \
444                             if self.annotationFiles[name] == filename].pop()
[1118]445            except Exception:
446                pass
[1710]447            self.useAttrNames = data_hints.get_hint(data, "genesinrows",
448                                                    self.useAttrNames)
[416]449            self.openContext("", data)
[985]450            self.Update()
[188]451        else:
[770]452            self.infoLabel.setText("No data on input\n")
[1248]453            self.warning(0)
454            self.warning(1)
[416]455            self.openContext("", None)
[188]456            self.ClearGraph()
457            self.send("Selected Examples", None)
458            self.send("Unselected Examples", None)
459            self.send("Example With Unknown Genes", None)
[1710]460            self.send("Enrichment Report", None)
[188]461
462    def SetReferenceDataset(self, data=None):
[1710]463        self.referenceDataset = data
[770]464        self.referenceRadioBox.buttons[1].setDisabled(not bool(data))
[921]465        self.referenceRadioBox.buttons[1].setText("Reference set")
[854]466        if self.clusterDataset and self.useReferenceDataset:
[921]467            self.useReferenceDataset = 0 if not data else 1
[854]468            graph = self.Enrichment()
[188]469            self.SetGraph(graph)
[921]470        elif self.clusterDataset:
471            self.UpdateReferenceSetButton()
[1710]472
[921]473    def UpdateReferenceSetButton(self):
474        allgenes, refgenes = None, None
475        if self.referenceDataset:
476            try:
477                allgenes = self.GenesFromExampleTable(self.referenceDataset)
478            except Exception:
479                allgenes = []
480            refgenes, unknown = self.FilterAnnotatedGenes(allgenes)
481        self.referenceRadioBox.buttons[1].setDisabled(not bool(allgenes))
482        self.referenceRadioBox.buttons[1].setText("Reference set " + ("(%i genes, %i matched)" % (len(allgenes), len(refgenes)) if allgenes and refgenes else ""))
[188]483
[921]484    def GenesFromExampleTable(self, data):
485        if self.useAttrNames:
486            genes = [v.name for v in data.domain.variables]
487        else:
488            attr = self.candidateGeneAttrs[min(self.geneAttrIndex, len(self.candidateGeneAttrs) - 1)]
489            genes = [str(ex[attr]) for ex in data if not ex[attr].isSpecial()]
490            if any("," in gene for gene in genes):
491                self.information(0, "Separators detected in gene names. Assuming multiple genes per example.")
492                genes = reduce(list.__add__, (genes.split(",") for genes in genes))
493        return genes
494       
495    def FilterAnnotatedGenes(self, genes):
496        matchedgenes = self.annotations.GetGeneNamesTranslator(genes).values()
497        return matchedgenes, [gene for gene in genes if gene not in matchedgenes]
498       
[188]499    def FilterUnknownGenes(self):
[1153]500        if not self.useAttrNames and self.candidateGeneAttrs:
[559]501            geneAttr = self.candidateGeneAttrs[min(self.geneAttrIndex, len(self.candidateGeneAttrs)-1)]
[188]502            examples = []
503            for ex in self.clusterDataset:
[988]504                if not any(self.annotations.genematcher.match(n.strip()) for n in str(ex[geneAttr]).split(",")):
[188]505                    examples.append(ex)
[921]506
[188]507            self.send("Example With Unknown Genes", examples and orange.ExampleTable(examples) or None)
508        else:
509            self.send("Example With Unknown Genes", None)
510
[1014]511    def Load(self, pb=None):
[985]512        go_files, tax_files = orngServerFiles.listfiles("GO"), orngServerFiles.listfiles("Taxonomy")
513        calls = []
[1014]514        pb, finish = (OWGUI.ProgressBar(self, 0), True) if pb is None else (pb, False)
[985]515        count = 0
516        if not tax_files:
517            calls.append(("Taxonomy", "ncbi_taxnomy.tar.gz"))
518            count += 1
519        org = self.annotationCodes[min(self.annotationIndex, len(self.annotationCodes)-1)]
520        if org != self.loadedAnnotationCode:
521            count += 1
[988]522            if self.annotationFiles[org] not in go_files:
523                calls.append(("GO", self.annotationFiles[org]))
[985]524                count += 1
525               
526        if "gene_ontology_edit.obo.tar.gz" not in go_files:
527            calls.append(("GO", "gene_ontology_edit.obo.tar.gz"))
528            count += 1
529        if not self.ontology:
530            count += 1
[1014]531        pb.iter += count*100
[1328]532       
[985]533        for i, args in enumerate(calls):
[1014]534            orngServerFiles.localpath_download(*args, **dict(callback=pb.advance))
[985]535           
536        i = len(calls)
537        if not self.ontology:
[1328]538            self.ontology = obiGO.Ontology(progressCallback=lambda value: pb.advance())
[985]539            i+=1
540        if org != self.loadedAnnotationCode:
[1352]541            self.annotations = None
542            gc.collect() # Force run garbage collection.
[988]543            code = self.annotationFiles[org].split(".")[-3]
[1328]544            self.annotations = obiGO.Annotations(code, genematcher=obiGene.GMDirect(), progressCallback=lambda value: pb.advance())
[985]545            i+=1
546            self.loadedAnnotationCode = org
[188]547            count = defaultdict(int)
548            geneSets = defaultdict(set)
[921]549
[540]550            for anno in self.annotations.annotations:
[188]551                count[anno.evidence]+=1
552                geneSets[anno.evidence].add(anno.geneName)
[540]553            for etype in obiGO.evidenceTypesOrdered:
[188]554                self.evidenceCheckBoxDict[etype].setEnabled(bool(count[etype]))
555                self.evidenceCheckBoxDict[etype].setText(etype+": %i annots(%i genes)" % (count[etype], len(geneSets[etype])))
[1014]556        if finish:
557            pb.finish()
[985]558           
[988]559    def SetGeneMatcher(self):
560        if self.annotations:
561            taxid = self.annotations.taxid
562            matchers = []
563            for matcher, use in zip([obiGene.GMGO, obiGene.GMKEGG, obiGene.GMNCBI, obiGene.GMAffy], self.geneMatcherSettings):
564                if use:
565                    try:
[1064]566                        if taxid == "352472":
[1330]567                            matchers.extend([matcher(taxid), obiGene.GMDicty(),
568                                            [matcher(taxid), obiGene.GMDicty()]])
569                            # The reason machers are duplicated is that we want `matcher` or `GMDicty` to
570                            # match genes by them self if possible. Only use the joint matcher if they fail.   
[1064]571                        else:
572                            matchers.append(matcher(taxid))
[988]573                    except Exception, ex:
574                        print ex
575            self.annotations.genematcher = obiGene.matcher(matchers)
[1014]576            self.annotations.genematcher.set_targets(self.annotations.geneNames)
[988]577           
[1014]578    def Enrichment(self, pb=None):
579        pb = OWGUI.ProgressBar(self, 100) if pb is None else pb
[559]580        if not self.annotations.ontology:
581            self.annotations.ontology = self.ontology
[921]582           
[988]583        if isinstance(self.annotations.genematcher, obiGene.GMDirect):
584            self.SetGeneMatcher()
[1153]585        self.error(1)
[1248]586        self.warning([0, 1])
[1153]587        try:   
588            if self.useAttrNames:
589                clusterGenes = [v.name for v in self.clusterDataset.domain.variables]
590                self.information(0)
[209]591            else:
[1153]592                geneAttr = self.candidateGeneAttrs[min(self.geneAttrIndex, len(self.candidateGeneAttrs)-1)]
593                clusterGenes = [str(ex[geneAttr]) for ex in self.clusterDataset if not ex[geneAttr].isSpecial()]
594                if any("," in gene for gene in clusterGenes):
595                    self.information(0, "Separators detected in cluster gene names. Assuming multiple genes per example.")
596                    clusterGenes = reduce(list.__add__, (genes.split(",") for genes in clusterGenes))
597                else:
598                    self.information(0)
599        except Exception, ex:
600            self.error(1, "Failed to extract gene names from input dataset! %s" % str(ex))
601            return {}
[770]602        genesCount = len(clusterGenes)
[1330]603        genesSetCount = len(set(clusterGenes))
[921]604       
[988]605        self.clusterGenes = clusterGenes = self.annotations.GetGeneNamesTranslator(clusterGenes).values()
606       
607#        self.clusterGenes = clusterGenes = filter(lambda g: g in self.annotations.aliasMapper or g in self.annotations.additionalAliases, clusterGenes)
[1330]608        self.infoLabel.setText("%i unique genes on input\n%i (%.1f%%) genes with known annotations" % (genesSetCount, len(clusterGenes), 100.0*len(clusterGenes)/genesSetCount if genesSetCount else 0.0))
[921]609       
[188]610        referenceGenes = None
[921]611        if self.referenceDataset:
[188]612            try:
613                if self.useAttrNames:
614                    referenceGenes = [v.name for v in self.referenceDataset.domain.variables]
[209]615                    self.information(1)
[188]616                else:
617                    referenceGenes = [str(ex[geneAttr]) for ex in self.referenceDataset if not ex[geneAttr].isSpecial()]
[209]618                    if any("," in gene for gene in clusterGenes):
619                        self.information(1, "Separators detected in reference gene names. Assuming multiple genes per example.")
620                        referenceGenes = reduce(list.__add__, (genes.split(",") for genes in referenceGenes))
621                    else:
622                        self.information(1)
[921]623
624                refc = len(referenceGenes)
[988]625#                referenceGenes = filter(lambda g: g in self.annotations.aliasMapper or g in self.annotations.additionalAliases, referenceGenes)
626                referenceGenes = self.annotations.GetGeneNamesTranslator(referenceGenes).values()
[921]627                self.referenceRadioBox.buttons[1].setText("Reference set (%i genes, %i matched)" % (refc, len(referenceGenes)))
628                self.referenceRadioBox.buttons[1].setDisabled(False)
[209]629                self.information(2)
[188]630            except Exception, er:
[921]631                if not self.referenceDataset:
632                    self.information(2, "Unable to extract gene names from reference dataset. Using entire genome for reference")
633                else:
634                    self.referenceRadioBox.buttons[1].setText("Reference set")
635                    self.referenceRadioBox.buttons[1].setDisabled(True)
[845]636                referenceGenes = self.annotations.geneNames
[854]637                self.useReferenceDataset = 0
[188]638        else:
[921]639            self.useReferenceDataset = 0
640        if not self.useReferenceDataset:
[209]641            self.information(2)
[921]642            self.information(1)
[540]643            referenceGenes = self.annotations.geneNames
[209]644        self.referenceGenes = referenceGenes
[188]645        evidences = []
[540]646        for etype in obiGO.evidenceTypesOrdered:
[188]647            if getattr(self, "useEvidence"+etype):
648                evidences.append(etype)
[217]649        aspect = ["P", "C", "F"][self.aspectIndex]
[1328]650       
[188]651        if clusterGenes:
[801]652            self.terms = terms = self.annotations.GetEnrichedTerms(clusterGenes, referenceGenes, evidences, aspect=aspect,
[1099]653                                                                   prob=self.probFunctions[self.probFunc], useFDR=self.useFDR,
[1328]654                                                                   progressCallback=lambda value:pb.advance() )
[188]655        else:
656            self.terms = terms = {}
[438]657        if not self.terms:
[1248]658            self.warning(0, "No enriched terms found.")
[438]659        else:
660            self.warning(0)
[1328]661           
[1014]662        pb.finish()
[188]663        self.treeStructDict = {}
664        ids = self.terms.keys()
[1139]665       
666        self.treeStructRootKey = None
[1352]667       
668        parents = {}
669        for id in ids:
670            parents[id] = set([term for typeId, term in self.ontology[id].related])
671           
672        children = {}
[188]673        for term in self.terms:
[1352]674            children[term] = set([id for id in ids if term in parents[id]])
675           
676        for term in self.terms:
677            self.treeStructDict[term] = TreeNode(self.terms[term], children[term])
[799]678            if not self.ontology[term].related and not getattr(self.ontology[term], "is_obsolete", False):
[188]679                self.treeStructRootKey = term
680        return terms
681       
682    def FilterGraph(self, graph):
683        if self.filterByPValue:
[540]684            graph = obiGO.filterByPValue(graph, self.maxPValue)
[188]685        if self.filterByNumOfInstances:
686            graph = dict(filter(lambda (id,(genes, p, rc)):len(genes)>=self.minNumOfInstances, graph.items()))
687        return graph
688
689    def FilterAndDisplayGraph(self):
690        if self.clusterDataset:
691            self.graph = self.FilterGraph(self.originalGraph)
[1248]692            if self.originalGraph and not self.graph:
693                self.warning(1, "All found terms were filtered out.")
694            else:
695                self.warning(1)
[188]696            self.ClearGraph()
697            self.DisplayGraph()
698
699    def SetGraph(self, graph=None):
700        self.originalGraph = graph
701        if graph:
702            self.FilterAndDisplayGraph()
703        else:
704            self.graph = {}
705            self.ClearGraph()
706
707    def ClearGraph(self):
708        self.listView.clear()
709        self.listViewItems=[]
[511]710        self.sigTerms.clear()
[188]711
712    def DisplayGraph(self):
713        fromParentDict = {}
714        self.termListViewItemDict = {}
[1710]715        self.listViewItems = []
[188]716        enrichment = lambda t:float(len(t[0])) / t[2] * (float(len(self.referenceGenes))/len(self.clusterGenes))
717        maxFoldEnrichment = max([enrichment(term) for term in self.graph.values()] or [1])
[1710]718
[188]719        def addNode(term, parent, parentDisplayNode):
720            if (parent, term) in fromParentDict:
721                return
722            if term in self.graph:
[851]723                displayNode = GOTreeWidgetItem(self.ontology[term], self.graph[term], len(self.clusterGenes), len(self.referenceGenes), maxFoldEnrichment, parentDisplayNode)
[921]724                displayNode.goId = term
[188]725                self.listViewItems.append(displayNode)
726                if term in self.termListViewItemDict:
727                    self.termListViewItemDict[term].append(displayNode)
728                else:
729                    self.termListViewItemDict[term] = [displayNode]
730                fromParentDict[(parent, term)] = True
731                parent = term
732            else:
733                displayNode = parentDisplayNode
[1710]734
[188]735            for c in self.treeStructDict[term].children:
736                addNode(c, parent, displayNode)
[1710]737
[1139]738        if self.treeStructDict:
739            addNode(self.treeStructRootKey, None, self.listView)
[188]740
741        terms = self.graph.items()
[1352]742        terms = sorted(terms, key=lambda item: item[1][1])
[188]743        self.sigTableTermsSorted = [t[0] for t in terms]
[1710]744
[511]745        self.sigTerms.clear()
[1710]746        for i, (t_id, (genes, p_value, refCount)) in enumerate(terms):
747            item = GOTreeWidgetItem(self.ontology[t_id],
748                                    (genes, p_value, refCount),
749                                    len(self.clusterGenes),
750                                    len(self.referenceGenes),
751                                    maxFoldEnrichment,
752                                    self.sigTerms)
753            item.goId = t_id
754
[196]755        self.listView.expandAll()
[899]756        for i in range(4):
757            self.listView.resizeColumnToContents(i)
758            self.sigTerms.resizeColumnToContents(i)
759        self.sigTerms.resizeColumnToContents(5)
760        width = min(self.listView.columnWidth(0), 350)
[851]761        self.listView.setColumnWidth(0, width)
762        self.sigTerms.setColumnWidth(0, width)
[1710]763
764        # Create and send the enrichemnt report table.
765        termsDomain = orange.Domain(
766            [orange.StringVariable("GO Term Id"),
767             orange.StringVariable("GO Term Name"),
768             orange.FloatVariable("Cluster Frequency"),
769             orange.FloatVariable("Reference Frequency"),
770             orange.FloatVariable("P-value"),
771             orange.FloatVariable("Enrichment"),
772             orange.StringVariable("Genes")
773             ], None)
774
775        terms = [[t_id,
776                  self.ontology[t_id].name,
777                  float(len(genes)) / len(self.clusterGenes),
778                  float(r_count) / len(self.referenceGenes),
779                  p_value,
780                  float(len(genes)) / len(self.clusterGenes) * \
781                  float(len(self.referenceGenes)) / r_count,
782                  ",".join(genes)
783                  ]
784                 for t_id, (genes, p_value, r_count) in terms]
785
786        if terms:
787            termsTable = orange.ExampleTable(termsDomain, terms)
788        else:
789            termsTable = orange.ExampleTable(termsDomain)
790        self.send("Enrichment Report", termsTable)
791
[188]792    def ViewSelectionChanged(self):
[219]793        if self.selectionChanging:
794            return
[1710]795
[219]796        self.selectionChanging = 1
797        self.selectedTerms = []
798        selected = self.listView.selectedItems()
[921]799        self.selectedTerms = list(set([lvi.term.id for lvi in selected]))
[188]800        self.ExampleSelection()
[219]801        self.selectionChanging = 0
[1710]802
[188]803    def TableSelectionChanged(self):
[219]804        if self.selectionChanging:
805            return
806       
807        self.selectionChanging = 1
[196]808        self.selectedTerms = []
[731]809        selectedIds = set([self.sigTerms.itemFromIndex(index).goId for index in self.sigTerms.selectedIndexes()])
[219]810       
[731]811        for i in range(self.sigTerms.topLevelItemCount()):
812            item = self.sigTerms.topLevelItem(i)
813            selected = item.goId in selectedIds
814            term = item.goId
[219]815           
[188]816            if selected:
817                self.selectedTerms.append(term)
[219]818               
[188]819            for lvi in self.termListViewItemDict[term]:
820                try:
821                    lvi.setSelected(selected)
[196]822                    if selected: lvi.setExpanded(True)
[188]823                except RuntimeError:    ##Underlying C/C++ object deleted (why??)
824                    pass
[196]825               
[188]826        self.ExampleSelection()
[219]827        self.selectionChanging = 0
[188]828           
829   
[1328]830    def UpdateAddClassButton(self):
831        self.addClassCB.setEnabled(self.selectionDisjoint == 1)
832       
[188]833    def ExampleSelection(self):
834        selectedExamples = []
835        unselectedExamples = []
836        selectedGenes = []
[1099]837       
[854]838        #change by Marko. don't do anything if there is no3 dataset
[188]839        if not self.clusterDataset:
840            return
[860]841       
842        selectedGenes = reduce(set.union, [v[0] for id, v in self.graph.items() if id in self.selectedTerms], set())
843        evidences = []
844        for etype in obiGO.evidenceTypesOrdered:
845            if getattr(self, "useEvidence"+etype):
846                evidences.append(etype)
[1328]847        allTerms = self.annotations.GetAnnotatedTerms(selectedGenes, 
848                          directAnnotationOnly=self.selectionDirectAnnotation, 
849                          evidenceCodes=evidences)
[188]850           
851        if self.selectionDisjoint:
[860]852            count = defaultdict(int)
[188]853            for term in self.selectedTerms:
[860]854                for g in allTerms.get(term, []):
[188]855                    count[g]+=1
[860]856            ccount = 1 if self.selectionDisjoint==1 else len(self.selectedTerms)
857            selectedGenes = [gene for gene, c in count.items() if c==ccount and gene in selectedGenes]
858        else:
859            selectedGenes = reduce(set.union, [allTerms.get(term, []) for term in self.selectedTerms], set())
[188]860
861        if self.useAttrNames:
862            vars = [self.clusterDataset.domain[gene] for gene in set(selectedGenes)]
[209]863            newDomain = orange.Domain(vars, self.clusterDataset.domain.classVar)
[1099]864            newdata = orange.ExampleTable(newDomain, self.clusterDataset)
865            self.send("Selected Examples", newdata)
[188]866            self.send("Unselected Examples", None)
[1160]867        elif self.candidateGeneAttrs:
[559]868            geneAttr = self.candidateGeneAttrs[min(self.geneAttrIndex, len(self.candidateGeneAttrs)-1)]
[1328]869            if self.selectionDisjoint == 1:
870                goVar = orange.EnumVariable("GO Term", values=list(self.selectedTerms))
871                newDomain = orange.Domain(self.clusterDataset.domain.variables, goVar)
872                newDomain.addmetas(self.clusterDataset.domain.getmetas())
873#            else:
874#                goVar = orange.StringVariable("GO Terms")
875#                newDomain = orange.Domain(self.clusterDataset.domain)
876#                newDomain.addmeta(orange.newmetaid(), goVar)
877           
878           
[188]879            for ex in self.clusterDataset:
[209]880                if not ex[geneAttr].isSpecial() and any(gene in selectedGenes for gene in str(ex[geneAttr]).split(",")):
[1328]881                    if self.selectionDisjoint == 1 and self.selectionAddTermAsClass:
882                        terms = filter(lambda term: any(gene in self.graph[term][0] for gene in str(ex[geneAttr]).split(",")) , self.selectedTerms)
883                        term = sorted(terms)[0]
[188]884                        ex =  orange.Example(newDomain, ex)
[1328]885                        ex[goVar] = goVar(term)
886#                        ex.setclass(newClass(term))
[188]887                    selectedExamples.append(ex)
888                else:
889                    unselectedExamples.append(ex)
[1099]890                   
891            if selectedExamples:
892                selectedExamples = orange.ExampleTable(selectedExamples)
893            else:
894                selectedExamples = None
895               
896            if unselectedExamples:
897                unselectedExamples = orange.ExampleTable(unselectedExamples)
898            else:
899                unselectedExamples = None
[1710]900
[1099]901            self.send("Selected Examples", selectedExamples)
902            self.send("Unselected Examples", unselectedExamples)
[638]903
[642]904    def ShowInfo(self):
905        dialog = QDialog(self)
[854]906        dialog.setModal(False)
[642]907        dialog.setLayout(QVBoxLayout())
908        label = QLabel(dialog)
909        label.setText("Ontology:\n"+self.ontology.header if self.ontology else "Ontology not loaded!")
910        dialog.layout().addWidget(label)
911
912        label = QLabel(dialog)
913        label.setText("Annotations:\n"+self.annotations.header.replace("!", "") if self.annotations else "Annotations not loaded!")
914        dialog.layout().addWidget(label)
915        dialog.show()
[985]916       
[799]917    def sendReport(self):
[802]918        self.reportSettings("Settings", [("Organism", self.annotationCodes[min(self.annotationIndex, len(self.annotationCodes) - 1)]),
919                                         ("Significance test", ("Binomial" if self.probFunc == 0 else "Hypergeometric") + (" with FDR" if self.useFDR else ""))])
920        self.reportSettings("Filter", ([("Min cluster size", self.minNumOfInstances)] if self.filterByNumOfInstances else []) + \
921                                      ([("Max p-value", self.maxPValue)] if self.filterByPValue else []))
[921]922
923        def treeDepth(item):
924            return 1 + max([treeDepth(item.child(i)) for i in range(item.childCount())] +[0])
925       
926        def printTree(item, level, treeDepth):
927            text = '<tr>' + '<td width=16px></td>' * level
928            text += '<td colspan="%i">%s: %s</td>' % (treeDepth - level, item.term.id, item.term.name)
[854]929            text += ''.join('<td>%s</td>' % item.text(i) for i in range(1, 4) + [5]) + '</tr>\n'
930            for i in range(item.childCount()):
[921]931                text += printTree(item.child(i), level + 1, treeDepth)
932            return text
933       
934        treeDepth = max([treeDepth(self.listView.topLevelItem(i)) for i in range(self.listView.topLevelItemCount())] + [0])
935       
936        tableText = '<table>\n<tr>' + ''.join('<th>%s</th>' % s for s in ["Term:", "List:", "Reference:", "P-value:", "Enrichment:"]) + '</tr>'
937       
938        treeText = '<table>\n' +  '<th colspan="%i">%s</th>' % (treeDepth, "Term:") 
939        treeText += ''.join('<th>%s</th>' % s for s in ["List:", "Reference:", "P-value:", "Enrichment:"]) + '</tr>'
[854]940       
941        for index in range(self.sigTerms.topLevelItemCount()):
942            item = self.sigTerms.topLevelItem(index)
[921]943            tableText += printTree(item, 0, 1) 
[854]944        tableText += '</table>' 
945       
946        for index in range(self.listView.topLevelItemCount()):
947            item = self.listView.topLevelItem(index)
[921]948            treeText += printTree(item, 0, treeDepth)
[854]949       
[921]950        self.reportSection("Enriched Terms")
[854]951        self.reportRaw(tableText)
[921]952       
953        self.reportSection("Enriched Terms in the Ontology Tree")
[854]954        self.reportRaw(treeText)
[1248]955       
956    def onStateChanged(self, stateType, id, text):
957        if stateType == "Warning":
958            self.listView._userMessage = text
959            self.listView.viewport().update()
[1411]960           
961    def onDeleteWidget(self):
962        """ Called before the widget is removed from the canvas.
963        """
964        self.annotations = None
965        self.ontology = None
966        gc.collect() # Force collection
967       
[799]968
[851]969class GOTreeWidgetItem(QTreeWidgetItem):
970    def __init__(self, term, enrichmentResult, nClusterGenes, nRefGenes, maxFoldEnrichment, parent):
971        QTreeWidgetItem.__init__(self, parent)
972        self.term = term
973        self.enrichmentResult = enrichmentResult
974        self.nClusterGenes = nClusterGenes
975        self.nRefGenes = nRefGenes
976        self.maxFoldEnrichment = maxFoldEnrichment
977        self.enrichment = enrichment = lambda t:float(len(t[0])) / t[2] * (float(nRefGenes)/nClusterGenes)
978        self.setText(0, term.name)
979        fmt = "%" + str(-int(math.log(nClusterGenes))) + "i (%.2f%%)"
980        self.setText(1, fmt % (len(enrichmentResult[0]), 100.0*len(self.enrichmentResult[0])/nClusterGenes))
981        fmt = "%" + str(-int(math.log(nRefGenes))) + "i (%.2f%%)"
982        self.setText(2, fmt % (enrichmentResult[2], 100.0*enrichmentResult[2]/nRefGenes))
983        self.setText(3, "%.4f" % enrichmentResult[1])
984        self.setText(4, ", ".join(enrichmentResult[0]))
[1328]985        self.setText(5, "%.2f" % (enrichment(enrichmentResult)))
[851]986        self.setToolTip(0, "<p>" + term.__repr__()[6:].strip().replace("\n", "<br>"))
987        self.sortByData = [term.name, len(self.enrichmentResult[0]), enrichmentResult[2], enrichmentResult[1], ", ".join(enrichmentResult[0]), enrichment(enrichmentResult)]
988
989    def data(self, col, role):
990        if role == Qt.UserRole:
991            return QVariant(self.enrichment(self.enrichmentResult) / self.maxFoldEnrichment)
992        else:
993            return QTreeWidgetItem.data(self, col, role)
994
995    def __lt__(self, other):
996        col = self.treeWidget().sortColumn()
997        return self.sortByData[col] < other.sortByData[col]
998   
[416]999class EnrichmentColumnItemDelegate(QItemDelegate):
1000    def paint(self, painter, option, index):
1001        self.drawBackground(painter, option, index)
[851]1002        value, ok = index.data(Qt.UserRole).toDouble()
[416]1003        if ok:
1004            painter.save()
1005            painter.setBrush(QBrush(Qt.white, Qt.SolidPattern))
1006            painter.drawRect(option.rect)
1007            painter.setBrush(QBrush(Qt.blue, Qt.SolidPattern))
1008            painter.drawRect(option.rect.x(), option.rect.y(), value*(option.rect.width()-1), option.rect.height()-1)
1009            painter.restore()
[188]1010        else:
[416]1011            QItemDelegate.paint(self, painter, option, index)
1012       
1013       
[988]1014class GeneMatcherDialog(OWWidget):
1015    items = [("useGO", "Use gene names from Gene Ontology annotations"),
1016             ("useKEGG", "Use gene names from KEGG Genes database"),
1017             ("useNCBI", "Use gene names from NCBI Gene info database"),
1018             ("useAffy", "Use Affymetrix platform reference ids")]
1019    settingsList = [item[0] for item in items]
1020    def __init__(self, parent=None, defaults=[True, False, False, False], enabled=[False, True, True, True], **kwargs):
1021        OWWidget.__init__(self, parent, **kwargs)
1022        for item, default in zip(self.items, defaults):
1023            setattr(self, item[0], default)
1024           
1025        self.loadSettings()
1026        for item, enable in zip(self.items, enabled):
1027            cb = OWGUI.checkBox(self, self, *item)
1028            cb.setEnabled(enable)
1029           
1030        box = OWGUI.widgetBox(self, orientation="horizontal")
1031        OWGUI.button(box, self, "OK", callback=self.accept)
1032        OWGUI.button(box, self, "Cancel", callback=self.reject)
1033       
1034       
[188]1035if __name__=="__main__":
1036    import sys
1037    app = QApplication(sys.argv)
1038    w=OWGOEnrichmentAnalysis()
[1748]1039    data = orange.ExampleTable("brown-selected.tab")
[416]1040    w.show()
[188]1041    w.SetClusterDataset(data)
[416]1042    app.exec_()
[188]1043    w.saveSettings()
1044       
Note: See TracBrowser for help on using the repository browser.