def __init__(self,parent=None, signalManager = None): OWWidget.__init__(self, parent, signalManager, "&Display Motifs", 0) # set default settings self.colorBy = None self.pvalThresholdIndex = None self.pvalThreshold = None #load settings self.loadSettings() # GUI self.graph = OWGraph(self.mainArea) self.graph.setYRlabels(None) self.graph.enableGridXB(0) self.graph.enableGridYL(1) self.graph.setAxisMaxMinor(QwtPlot.xBottom, 10) self.graph.setAxisMaxMajor(QwtPlot.xBottom, 10) self.graph.setAxisAutoScale(QwtPlot.xBottom) self.graph.setAxisScale(QwtPlot.xBottom, -1020, 0, 0) self.mainArea.layout().addWidget(self.graph) # inputs # data and graph temp variables self.inputs = [("Examples", ExampleTable, self.cdata, Default), ("Genes", list, self.newGeneList, Default), ("Motifs", list, self.newMotifList, Default)] self.data = None self.motifLines = [] self.visibleValues = [] self.valueToCurve = {} self.allGenes = [] ## genes displayed always in same order self.geneList = [] ## selected genes self.motifList = [] ## selected motifs self.valuesPresentInData = [] self.clusterPostProbThreshold = 0 # GUI self.selValues = OWGUI.widgetBox(self.controlArea, "Values") self.selcolorBy = OWGUI.widgetBox(self.controlArea, "Color By") self.colorByCombo = OWGUI.comboBox(self.selcolorBy, self, "colorBy", items=[], callback=self.colorByChanged) self.pvalThresholdCombo = OWGUI.comboBox(self.selValues, self, "pvalThresholdIndex", items=[], callback=self.pvalThresholdChanged) self.valuesQLB = QListWidget(self.selValues) self.valuesQLB.setSelectionMode(QListWidget.MultiSelection) self.connect(self.valuesQLB, SIGNAL("itemSelectionChanged()"), self.valuesSelectionChange) self.selValues.layout().addWidget(self.valuesQLB) self.unselectAllQLB = OWGUI.button(self.selValues, self, "Unselect all", callback = self.unselAll)
def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, "&Display Motifs", 0) # set default settings self.colorBy = None self.pvalThresholdIndex = None self.pvalThreshold = None #load settings self.loadSettings() # GUI self.graph = OWGraph(self.mainArea) self.graph.setYRlabels(None) self.graph.enableGridXB(0) self.graph.enableGridYL(1) self.graph.setAxisMaxMinor(QwtPlot.xBottom, 10) self.graph.setAxisMaxMajor(QwtPlot.xBottom, 10) self.graph.setAxisAutoScale(QwtPlot.xBottom) self.graph.setAxisScale(QwtPlot.xBottom, -1020, 0, 0) self.mainArea.layout().addWidget(self.graph) # inputs # data and graph temp variables self.inputs = [("Examples", ExampleTable, self.cdata, Default), ("Genes", list, self.newGeneList, Default), ("Motifs", list, self.newMotifList, Default)] self.data = None self.motifLines = [] self.visibleValues = [] self.valueToCurve = {} self.allGenes = [] ## genes displayed always in same order self.geneList = [] ## selected genes self.motifList = [] ## selected motifs self.valuesPresentInData = [] self.clusterPostProbThreshold = 0 # GUI self.selValues = OWGUI.widgetBox(self.controlArea, "Values") self.selcolorBy = OWGUI.widgetBox(self.controlArea, "Color By") self.colorByCombo = OWGUI.comboBox(self.selcolorBy, self, "colorBy", items=[], callback=self.colorByChanged) self.pvalThresholdCombo = OWGUI.comboBox( self.selValues, self, "pvalThresholdIndex", items=[], callback=self.pvalThresholdChanged) self.valuesQLB = QListWidget(self.selValues) self.valuesQLB.setSelectionMode(QListWidget.MultiSelection) self.connect(self.valuesQLB, SIGNAL("itemSelectionChanged()"), self.valuesSelectionChange) self.selValues.layout().addWidget(self.valuesQLB) self.unselectAllQLB = OWGUI.button(self.selValues, self, "Unselect all", callback=self.unselAll)
class OWDisplayMotifs(OWWidget): settingsList = [] def __init__(self, parent=None, signalManager=None): OWWidget.__init__(self, parent, signalManager, "&Display Motifs", 0) # set default settings self.colorBy = None self.pvalThresholdIndex = None self.pvalThreshold = None #load settings self.loadSettings() # GUI self.graph = OWGraph(self.mainArea) self.graph.setYRlabels(None) self.graph.enableGridXB(0) self.graph.enableGridYL(1) self.graph.setAxisMaxMinor(QwtPlot.xBottom, 10) self.graph.setAxisMaxMajor(QwtPlot.xBottom, 10) self.graph.setAxisAutoScale(QwtPlot.xBottom) self.graph.setAxisScale(QwtPlot.xBottom, -1020, 0, 0) self.mainArea.layout().addWidget(self.graph) # inputs # data and graph temp variables self.inputs = [("Examples", ExampleTable, self.cdata, Default), ("Genes", list, self.newGeneList, Default), ("Motifs", list, self.newMotifList, Default)] self.data = None self.motifLines = [] self.visibleValues = [] self.valueToCurve = {} self.allGenes = [] ## genes displayed always in same order self.geneList = [] ## selected genes self.motifList = [] ## selected motifs self.valuesPresentInData = [] self.clusterPostProbThreshold = 0 # GUI self.selValues = OWGUI.widgetBox(self.controlArea, "Values") self.selcolorBy = OWGUI.widgetBox(self.controlArea, "Color By") self.colorByCombo = OWGUI.comboBox(self.selcolorBy, self, "colorBy", items=[], callback=self.colorByChanged) self.pvalThresholdCombo = OWGUI.comboBox( self.selValues, self, "pvalThresholdIndex", items=[], callback=self.pvalThresholdChanged) self.valuesQLB = QListWidget(self.selValues) self.valuesQLB.setSelectionMode(QListWidget.MultiSelection) self.connect(self.valuesQLB, SIGNAL("itemSelectionChanged()"), self.valuesSelectionChange) self.selValues.layout().addWidget(self.valuesQLB) self.unselectAllQLB = OWGUI.button(self.selValues, self, "Unselect all", callback=self.unselAll) def unselAll(self): self.valuesQLB.clearSelection() def pvalThresholdChanged(self): print self.pvalThresholdIndex if self.pvalThresholdIndex: self.pvalThreshold = float( self.pvalThresholdCombo.text(self.pvalThresholdIndex)) else: self.pvalThreshold = None self.calcMotifsGraph() self.updateMotifsGraph() def valuesSelectionChange(self): visibleOutcomes = [] for i in range(self.valuesQLB.count()): item = self.valuesQLB.item(i) if item.isSelected(): visibleOutcomes.append(str(item.text())) self.visibleValues = visibleOutcomes self.updateMotifsGraph() def updateSelectionChange(self): ## make new colors only for those colorBy values present in data colors = ColorPaletteHSV(len(self.valuesPresentInData)) for (i, v) in enumerate(self.valuesPresentInData): curve = self.valueToCurve[v] curve.color = colors[i] self.setValuesNames(self.valuesPresentInData) for i in range(self.valuesQLB.count()): item = self.valuesQLB.item(i) item.setSelected(str(item.text()) in self.visibleValues) # else: # self.valuesQLB.setSelected(i, 0) def colorByChanged(self): # self.graph.removeCurves() self.graph.removeDrawingCurves() self.valueToCurve = {} if self.colorBy == None: self.setValuesNames(None) return if self.potentialColorVariables: var = self.potentialColorVariables[self.colorBy] values = sorted(var.values) # values.sort() ## generate colors for each colorby value (each color on its own curve) colors = ColorPaletteHSV(len(values)) for (i, v) in enumerate(values): ## create curve in graph curve = subBarQwtPlotCurve() curve.color = colors[i] curve.attach(self.graph) # ckey = self.graph.insertCurve(curve) curve.setStyle(QwtPlotCurve.UserCurve) self.valueToCurve[v] = curve self.setValuesNames(values) self.calcMotifsGraph() def setValuesNames(self, values): self.valuesQLB.clear() if values == None: return for v in values: self.valuesQLB.addItem( QListWidgetItem(QIcon(ColorPixmap(self.valueToCurve[v].color)), v)) self.valuesQLB.item(self.valuesQLB.count() - 1).setSelected(True) ## signal processing def newGeneList(self, list): self.geneList = [] if list is not None: self.geneList = list self.calcMotifsGraph() self.updateMotifsGraph() def newMotifList(self, list): self.motifList = [] if list is not None: self.motifList = list self.calcMotifsGraph() self.updateMotifsGraph() def cdata(self, data): self.data = data self.motifLines = [] self.colorByCombo.clear() if self.data == None: self.colorBy = None self.potentialColorVariables = [] self.colorByChanged() self.graph.setYLlabels(None) else: self.potentialColorVariables = [v for v in self.data.domain.variables + self.data.domain.getmetas().values() \ if v.varType == orange.VarTypes.Discrete] for var in self.potentialColorVariables: self.colorByCombo.addItem(str(var.name)) ## break motif info according to gene (sequenceID) self.motifLines = defaultdict(list) for e in self.data: geneID = str(e['sequenceID']) self.motifLines[geneID].append(e) self.allGenes = sorted(self.motifLines.keys()) if self.potentialColorVariables: self.colorBy = min( len(self.potentialColorVariables) - 1, self.colorBy or 0) else: self.colorBy = None self.colorByChanged() if len(self.potentialColorVariables) > 0: self.colorByCombo.setCurrentIndex(0) ## update graph def calcMotifsGraph(self): graphData = {} for (colorKey, curve) in self.valueToCurve.iteritems(): graphData[colorKey] = [[], []] lineCn = 0 yVals = [] self.colorByValuesPresentInData = [] self.valuesPresentInData = [] for lineKey in self.geneList: ## if (self.geneList <> None) and (self.geneList <> []) and (lineKey not in self.geneList): continue yVals.append(lineKey) for e in self.motifLines[lineKey]: motifName = str(e['motifName']) #.value if self.motifList is not None and self.motifList != [] and motifName not in self.motifList: continue motifDistToEnd = -int(e['distToEnd']) #.value) postProb = int(round(float(e['pvalue']) * 100)) dir = str(e['direction']) if 1 or ( postProb >= self.clusterPostProbThreshold ): ## and (chiSquare >= self.motifChiSquareThreshold): colorAttr = self.potentialColorVariables[self.colorBy] colorKey = str(e[colorAttr]) if colorKey not in self.valuesPresentInData: self.valuesPresentInData.append(colorKey) # print motifNumber, colorKey # set the point x values graphData[colorKey][0].append(motifDistToEnd) graphData[colorKey][0].append(motifDistToEnd + 5.0) # set the point y values if dir == "1": graphData[colorKey][1].append(lineCn + 0.0) graphData[colorKey][1].append(lineCn + 0.30) elif dir == "-1": graphData[colorKey][1].append(lineCn - 0.30) graphData[colorKey][1].append(lineCn + 0.0) else: graphData[colorKey][1].append(lineCn - 0.30) graphData[colorKey][1].append(lineCn + 0.30) lineCn += 1 vals = reduce(list.__add__, [val[0] for val in graphData.itervalues()], []) minX = min(vals or [0]) - 5.0 maxX = max(vals or [0]) + 5.0 self.graph.setYLlabels(yVals) self.graph.setAxisScale(QwtPlot.yLeft, -0.5, len(yVals) - 0.5, 1) self.graph.setAxisScale(QwtPlot.xBottom, minX, maxX) for (colorKey, curve) in self.valueToCurve.iteritems(): curve.setData(graphData[colorKey][0], graphData[colorKey][1]) curve.setVisible(colorKey in self.visibleValues) self.graph.replot() self.valuesPresentInData.sort() self.visibleValues = [v for v in self.valuesPresentInData] self.updateSelectionChange() def updateMotifsGraph(self): for (colorKey, curve) in self.valueToCurve.items(): curve.setVisible(colorKey in self.visibleValues) self.graph.replot()
def __init__(self, parent=None, signalManager=None, name="Normalize Expression Array"): OWWidget.__init__(self, parent, signalManager, name, wantGraph=True) self.inputs = [("Expression array", ExampleTable, self.setData)] self.outputs = [("Normalized expression array", ExampleTable, Default), ("Filtered expression array", ExampleTable)] self.selectedGroup = 0 self.selectedCenterMethod = 0 self.selectedMergeMethod = 0 self.zCutoff = 1.96 self.appendZScore = False self.appendRIValues = False self.autoCommit = False self.loadSettings() ## GUI self.infoBox = OWGUI.widgetLabel( OWGUI.widgetBox(self.controlArea, "Info", addSpace=True), "No data on input.") box = OWGUI.widgetBox(self.controlArea, "Split by", addSpace=True) self.groupCombo = OWGUI.comboBox(box, self, "selectedGroup", callback=self.onGroupSelection) self.centerCombo = OWGUI.comboBox( self.controlArea, self, "selectedCenterMethod", box="Center Fold-change Using", items=[name for name, _ in self.CENTER_METHODS], callback=self.onCenterMethodChange, addSpace=True) self.mergeCombo = OWGUI.comboBox( self.controlArea, self, "selectedMergeMethod", box="Merge Replicates", items=[name for name, _ in self.MERGE_METHODS], tooltip="Select the method for replicate merging", callback=self.onMergeMethodChange, addSpace=True) box = OWGUI.doubleSpin(self.controlArea, self, "zCutoff", 0.0, 3.0, 0.01, box="Z-Score Cutoff", callback=[self.replotMA, self.commitIf]) OWGUI.separator(self.controlArea) box = OWGUI.widgetBox(self.controlArea, "Ouput") OWGUI.checkBox(box, self, "appendZScore", "Append Z-Scores", tooltip="Append calculated Z-Scores to output", callback=self.commitIf) OWGUI.checkBox( box, self, "appendRIValues", "Append Log Ratio and Intensity values", tooltip= "Append calculated Log Ratio and Intensity values to output data", callback=self.commitIf) cb = OWGUI.checkBox(box, self, "autoCommit", "Commit on change", tooltip="Commit data on any change", callback=self.commitIf) b = OWGUI.button(box, self, "Commit", callback=self.commit) OWGUI.setStopper(self, b, cb, "changedFlag", callback=self.commit) self.connect(self.graphButton, SIGNAL("clicked()"), self.saveGraph) OWGUI.rubber(self.controlArea) self.graph = OWGraph(self.mainArea) self.graph.setAxisTitle(QwtPlot.xBottom, "Intensity: log<sub>10</sub>(R*G)") self.graph.setAxisTitle(QwtPlot.yLeft, "Log ratio: log<sub>2</sub>(R/G)") self.graph.showFilledSymbols = True self.mainArea.layout().addWidget(self.graph) self.groups = [] self.split_data = None, None self.merged_splits = None, None self.centered = None, None self.changedFlag = False self.data = None self.resize(800, 600)
class OWMAPlot(OWWidget): settingsList = ["appendZScore", "appendRIValues"] contextHandlers = { "": DomainContextHandler("", ["selectedGroup", "zCutoff"]) } CENTER_METHODS = [("Average", obiExpression.MA_center_average), ("Lowess (fast - interpolated)", obiExpression.MA_center_lowess_fast), ("Lowess", obiExpression.MA_center_lowess)] MERGE_METHODS = [("Average", numpy.ma.average), ("Median", numpy.ma.median), ("Geometric mean", obiExpression.geometric_mean)] def __init__(self, parent=None, signalManager=None, name="Normalize Expression Array"): OWWidget.__init__(self, parent, signalManager, name, wantGraph=True) self.inputs = [("Expression array", ExampleTable, self.setData)] self.outputs = [("Normalized expression array", ExampleTable, Default), ("Filtered expression array", ExampleTable)] self.selectedGroup = 0 self.selectedCenterMethod = 0 self.selectedMergeMethod = 0 self.zCutoff = 1.96 self.appendZScore = False self.appendRIValues = False self.autoCommit = False self.loadSettings() ## GUI self.infoBox = OWGUI.widgetLabel( OWGUI.widgetBox(self.controlArea, "Info", addSpace=True), "No data on input.") box = OWGUI.widgetBox(self.controlArea, "Split by", addSpace=True) self.groupCombo = OWGUI.comboBox(box, self, "selectedGroup", callback=self.onGroupSelection) self.centerCombo = OWGUI.comboBox( self.controlArea, self, "selectedCenterMethod", box="Center Fold-change Using", items=[name for name, _ in self.CENTER_METHODS], callback=self.onCenterMethodChange, addSpace=True) self.mergeCombo = OWGUI.comboBox( self.controlArea, self, "selectedMergeMethod", box="Merge Replicates", items=[name for name, _ in self.MERGE_METHODS], tooltip="Select the method for replicate merging", callback=self.onMergeMethodChange, addSpace=True) box = OWGUI.doubleSpin(self.controlArea, self, "zCutoff", 0.0, 3.0, 0.01, box="Z-Score Cutoff", callback=[self.replotMA, self.commitIf]) OWGUI.separator(self.controlArea) box = OWGUI.widgetBox(self.controlArea, "Ouput") OWGUI.checkBox(box, self, "appendZScore", "Append Z-Scores", tooltip="Append calculated Z-Scores to output", callback=self.commitIf) OWGUI.checkBox( box, self, "appendRIValues", "Append Log Ratio and Intensity values", tooltip= "Append calculated Log Ratio and Intensity values to output data", callback=self.commitIf) cb = OWGUI.checkBox(box, self, "autoCommit", "Commit on change", tooltip="Commit data on any change", callback=self.commitIf) b = OWGUI.button(box, self, "Commit", callback=self.commit) OWGUI.setStopper(self, b, cb, "changedFlag", callback=self.commit) self.connect(self.graphButton, SIGNAL("clicked()"), self.saveGraph) OWGUI.rubber(self.controlArea) self.graph = OWGraph(self.mainArea) self.graph.setAxisTitle(QwtPlot.xBottom, "Intensity: log<sub>10</sub>(R*G)") self.graph.setAxisTitle(QwtPlot.yLeft, "Log ratio: log<sub>2</sub>(R/G)") self.graph.showFilledSymbols = True self.mainArea.layout().addWidget(self.graph) self.groups = [] self.split_data = None, None self.merged_splits = None, None self.centered = None, None self.changedFlag = False self.data = None self.resize(800, 600) def onFinished(self, status): self.setEnabled(True) def onUnhandledException(self, ex_info): self.setEnabled(True) print >> sys.stderr, "Unhandled exception in non GUI thread" ex_type, ex_val, tb = ex_info if ex_type == numpy.linalg.LinAlgError and False: self.error(0, "Linear algebra error: %s" % repr(ex_val)) else: sys.excepthook(*ex_info) def onGroupSelection(self): if self.data: self.updateInfoBox() self.splitData() self.runNormalization() def onCenterMethodChange(self): if self.data: self.runNormalization() def onMergeMethodChange(self): if self.data: self.splitData() self.runNormalization() def proposeGroups(self, data): col_labels = [ attr.attributes.items() for attr in data.domain.attributes ] col_labels = sorted(reduce(set.union, col_labels, set())) col_labels = [(key, value, 1) for key, value in col_labels] attrs = [attr for attr in data.domain.variables + data.domain.getmetas().values() \ if attr.varType == orange.VarTypes.Discrete] row_labels = [(attr.name, value, 0) for attr in attrs for value in attr.values] def filterSingleValues(labels): ret = [] for name, value, axis in labels: match = [(n, v, a) for n, v, a in labels if n == name] if len(match) > 1: ret.append((name, value, axis)) return ret col_labels = filterSingleValues(col_labels) row_labels = filterSingleValues(row_labels) return col_labels + row_labels def setData(self, data): self.closeContext("") self.data = data self.error([0, 1]) if data is not None: self.infoBox.setText("%i genes on input" % len(data)) self.groups = self.proposeGroups(data) self.groupCombo.clear() self.groupCombo.addItems( ["%s: %s" % (key, value) for key, value, axis in self.groups]) if not self.groups: self.error( 1, "Input data has no class attribute or attribute labels!") self.clear() return self.openContext("", data) self.selectedGroup = min(self.selectedGroup, len(self.groups) - 1) self.updateInfoBox() self.splitData() self.runNormalization() else: self.clear() def clear(self): self.groups = [] self.data = None self.centered = None, None self.split_data = None, None self.merged_splits = None, None self.graph.removeDrawingCurves() self.infoBox.setText("No data on input") self.send("Normalized expression array", None) self.send("Filtered expression array", None) def updateInfoBox(self): genes = self.getGeneNames() self.infoBox.setText("%i genes on input" % len(self.data)) def getSelectedGroup(self): return self.groups[self.selectedGroup] def getSelectedGroupSplit(self): key, value, axis = self.getSelectedGroup() other_values = [ v for k, v, a in self.groups if k == key and a == axis and v != value ] return [(key, value), (key, other_values)], axis def getGeneNames(self): key, value, axis = self.getSelectedGroup() if axis == 0: genes = [str(ex[key]) for ex in self.data] else: genes = [attr.name for attr in self.data.domain.attributes] return genes def splitData(self): groups, axis = self.getSelectedGroupSplit() self.split_ind = [ obiExpression.select_indices(self.data, key, value, axis) for key, value in groups ] self.split_data = obiExpression.split_data(self.data, groups, axis) def getMerged(self): split1, split2 = self.split_data (array1, _, _), (array2, _, _) = split1.toNumpyMA(), split2.toNumpyMA() _, _, axis = self.getSelectedGroup() merge_function = self.MERGE_METHODS[self.selectedMergeMethod][1] merged1 = obiExpression.merge_replicates(array1, axis, merge_function=merge_function) merged2 = obiExpression.merge_replicates(array2, axis, merge_function=merge_function) self.merged_splits = merged1, merged2 return self.merged_splits def runNormalization(self): self.progressBarInit() self.progressBarSet(0.0) G, R = self.getMerged() self.progressBarSet(5.0) center_method = self.CENTER_METHODS[self.selectedCenterMethod][1] # TODO: progess bar , lowess can take a long time if self.selectedCenterMethod in [1, 2]: #Lowess Gc, Rc = center_method(G, R, f=1. / min(500., len(G) / 100), iter=1) else: Gc, Rc = center_method(G, R) self.progressBarSet(70.0) self.centered = Gc, Rc self.z_scores = obiExpression.MA_zscore(Gc, Rc, 1. / 3.) self.progressBarSet(100.0) self.plotMA(Gc, Rc, self.z_scores, self.zCutoff) self.progressBarFinished() def runNormalizationAsync(self): """ Run MA centering and z_score estimation in a separate thread """ self.error(0) self.progressBarInit() self.progressBarSet(0.0) G, R = self.getMerged() # self.progressBarSet(5.0) center_method = self.CENTER_METHODS[self.selectedCenterMethod][1] use_lowess = self.selectedCenterMethod in [1, 2] def run(progressCallback=lambda value: None ): # the function to run in a thread # progressCallback(5.0) if use_lowess: Gc, Rc = center_method( G, R, f=2. / 3., iter=1, progressCallback=lambda val: progressCallback(val / 2)) else: Gc, Rc = center_method(G, R) progressCallback(50) z_scores = obiExpression.MA_zscore( Gc, Rc, 1. / 3., progressCallback=lambda val: progressCallback(50 + val / 2)) return Gc, Rc, z_scores self.progressDiscard = ProgressBarDiscard(self, self) async = self.asyncCall(run, name="Normalization", onResult=self.onResults, onError=self.onUnhandledException) self.connect(async, SIGNAL("progressChanged(float)"), self.progressDiscard.progressBarSet, Qt.QueuedConnection) self.setEnabled(False) async .__call__(progressCallback=async .emitProgressChanged) ## comment out this line if threading creates any problems runNormalization = runNormalizationAsync def onResults(self, (Gc, Rc, z_scores)): """ Handle the results of centering and z-scoring """ assert (QThread.currentThread() is self.thread()) self.setEnabled(True) qApp.processEvents() self.progressBarFinished() self.centered = Gc, Rc self.z_scores = z_scores self.plotMA(Gc, Rc, z_scores, self.zCutoff) self.commit()
class OWDisplayMotifs(OWWidget): settingsList = [] def __init__(self,parent=None, signalManager = None): OWWidget.__init__(self, parent, signalManager, "&Display Motifs", 0) # set default settings self.colorBy = None self.pvalThresholdIndex = None self.pvalThreshold = None #load settings self.loadSettings() # GUI self.graph = OWGraph(self.mainArea) self.graph.setYRlabels(None) self.graph.enableGridXB(0) self.graph.enableGridYL(1) self.graph.setAxisMaxMinor(QwtPlot.xBottom, 10) self.graph.setAxisMaxMajor(QwtPlot.xBottom, 10) self.graph.setAxisAutoScale(QwtPlot.xBottom) self.graph.setAxisScale(QwtPlot.xBottom, -1020, 0, 0) self.mainArea.layout().addWidget(self.graph) # inputs # data and graph temp variables self.inputs = [("Examples", ExampleTable, self.cdata, Default), ("Genes", list, self.newGeneList, Default), ("Motifs", list, self.newMotifList, Default)] self.data = None self.motifLines = [] self.visibleValues = [] self.valueToCurve = {} self.allGenes = [] ## genes displayed always in same order self.geneList = [] ## selected genes self.motifList = [] ## selected motifs self.valuesPresentInData = [] self.clusterPostProbThreshold = 0 # GUI self.selValues = OWGUI.widgetBox(self.controlArea, "Values") self.selcolorBy = OWGUI.widgetBox(self.controlArea, "Color By") self.colorByCombo = OWGUI.comboBox(self.selcolorBy, self, "colorBy", items=[], callback=self.colorByChanged) self.pvalThresholdCombo = OWGUI.comboBox(self.selValues, self, "pvalThresholdIndex", items=[], callback=self.pvalThresholdChanged) self.valuesQLB = QListWidget(self.selValues) self.valuesQLB.setSelectionMode(QListWidget.MultiSelection) self.connect(self.valuesQLB, SIGNAL("itemSelectionChanged()"), self.valuesSelectionChange) self.selValues.layout().addWidget(self.valuesQLB) self.unselectAllQLB = OWGUI.button(self.selValues, self, "Unselect all", callback = self.unselAll) def unselAll(self): self.valuesQLB.clearSelection() def pvalThresholdChanged(self): print self.pvalThresholdIndex if self.pvalThresholdIndex: self.pvalThreshold = float(self.pvalThresholdCombo.text(self.pvalThresholdIndex)) else: self.pvalThreshold = None self.calcMotifsGraph() self.updateMotifsGraph() def valuesSelectionChange(self): visibleOutcomes = [] for i in range(self.valuesQLB.count()): item = self.valuesQLB.item(i) if item.isSelected(): visibleOutcomes.append(str(item.text())) self.visibleValues = visibleOutcomes self.updateMotifsGraph() def updateSelectionChange(self): ## make new colors only for those colorBy values present in data colors = ColorPaletteHSV(len(self.valuesPresentInData)) for (i, v) in enumerate(self.valuesPresentInData): curve = self.valueToCurve[v] curve.color = colors[i] self.setValuesNames(self.valuesPresentInData) for i in range(self.valuesQLB.count()): item = self.valuesQLB.item(i) item.setSelected(str(item.text()) in self.visibleValues) # else: # self.valuesQLB.setSelected(i, 0) def colorByChanged(self): # self.graph.removeCurves() self.graph.removeDrawingCurves() self.valueToCurve = {} if self.colorBy == None: self.setValuesNames(None) return if self.potentialColorVariables: var = self.potentialColorVariables[self.colorBy] values = sorted(var.values) # values.sort() ## generate colors for each colorby value (each color on its own curve) colors = ColorPaletteHSV(len(values)) for (i, v) in enumerate(values): ## create curve in graph curve = subBarQwtPlotCurve() curve.color = colors[i] curve.attach(self.graph) # ckey = self.graph.insertCurve(curve) curve.setStyle(QwtPlotCurve.UserCurve) self.valueToCurve[v] = curve self.setValuesNames(values) self.calcMotifsGraph() def setValuesNames(self, values): self.valuesQLB.clear() if values == None: return for v in values: self.valuesQLB.addItem(QListWidgetItem(QIcon(ColorPixmap(self.valueToCurve[v].color)), v)) self.valuesQLB.item(self.valuesQLB.count() - 1).setSelected(True) ## signal processing def newGeneList(self, list): self.geneList = [] if list is not None: self.geneList = list self.calcMotifsGraph() self.updateMotifsGraph() def newMotifList(self, list): self.motifList = [] if list is not None: self.motifList = list self.calcMotifsGraph() self.updateMotifsGraph() def cdata(self, data): self.data = data self.motifLines = [] self.colorByCombo.clear() if self.data == None: self.colorBy = None self.potentialColorVariables = [] self.colorByChanged() self.graph.setYLlabels(None) else: self.potentialColorVariables = [v for v in self.data.domain.variables + self.data.domain.getmetas().values() \ if v.varType == orange.VarTypes.Discrete] for var in self.potentialColorVariables: self.colorByCombo.addItem(str(var.name)) ## break motif info according to gene (sequenceID) self.motifLines = defaultdict(list) for e in self.data: geneID = str(e['sequenceID']) self.motifLines[geneID].append(e) self.allGenes = sorted(self.motifLines.keys()) if self.potentialColorVariables: self.colorBy = min(len(self.potentialColorVariables) - 1, self.colorBy or 0) else: self.colorBy = None self.colorByChanged() if len(self.potentialColorVariables) > 0: self.colorByCombo.setCurrentIndex(0) ## update graph def calcMotifsGraph(self): graphData = {} for (colorKey, curve) in self.valueToCurve.iteritems(): graphData[colorKey] = [[], []] lineCn = 0 yVals = [] self.colorByValuesPresentInData = [] self.valuesPresentInData = [] for lineKey in self.geneList: ## if (self.geneList <> None) and (self.geneList <> []) and (lineKey not in self.geneList): continue yVals.append( lineKey) for e in self.motifLines[lineKey]: motifName = str(e['motifName'])#.value if self.motifList is not None and self.motifList != [] and motifName not in self.motifList: continue motifDistToEnd = -int(e['distToEnd']) #.value) postProb = int(round(float(e['pvalue']) * 100)) dir = str(e['direction']) if 1 or (postProb >= self.clusterPostProbThreshold): ## and (chiSquare >= self.motifChiSquareThreshold): colorAttr = self.potentialColorVariables[self.colorBy] colorKey = str(e[colorAttr]) if colorKey not in self.valuesPresentInData: self.valuesPresentInData.append(colorKey) # print motifNumber, colorKey # set the point x values graphData[colorKey][0].append(motifDistToEnd) graphData[colorKey][0].append(motifDistToEnd + 5.0) # set the point y values if dir == "1": graphData[colorKey][1].append(lineCn + 0.0) graphData[colorKey][1].append(lineCn + 0.30) elif dir == "-1": graphData[colorKey][1].append(lineCn - 0.30) graphData[colorKey][1].append(lineCn + 0.0) else: graphData[colorKey][1].append(lineCn - 0.30) graphData[colorKey][1].append(lineCn + 0.30) lineCn += 1 vals = reduce(list.__add__, [val[0] for val in graphData.itervalues()], []) minX = min(vals or [0]) - 5.0 maxX = max(vals or [0]) + 5.0 self.graph.setYLlabels(yVals) self.graph.setAxisScale(QwtPlot.yLeft, -0.5, len(yVals) - 0.5, 1) self.graph.setAxisScale(QwtPlot.xBottom, minX, maxX) for (colorKey, curve) in self.valueToCurve.iteritems(): curve.setData(graphData[colorKey][0], graphData[colorKey][1]) curve.setVisible(colorKey in self.visibleValues) self.graph.replot() self.valuesPresentInData.sort() self.visibleValues = [v for v in self.valuesPresentInData] self.updateSelectionChange() def updateMotifsGraph(self): for (colorKey, curve) in self.valueToCurve.items(): curve.setVisible(colorKey in self.visibleValues) self.graph.replot()
def __init__(self, parent=None, signalManager=None, name="Normalize Expression Array"): OWWidget.__init__(self, parent, signalManager, name, wantGraph=True) self.inputs = [("Expression array", ExampleTable, self.setData)] self.outputs = [("Normalized expression array", ExampleTable, Default), ("Filtered expression array", ExampleTable)] self.selectedGroup = 0 self.selectedCenterMethod = 0 self.selectedMergeMethod = 0 self.zCutoff = 1.96 self.appendZScore = False self.appendRIValues = False self.autoCommit = False self.loadSettings() ## GUI self.infoBox = OWGUI.widgetLabel(OWGUI.widgetBox(self.controlArea, "Info", addSpace=True), "No data on input.") box = OWGUI.widgetBox(self.controlArea, "Split by", addSpace=True) self.groupCombo = OWGUI.comboBox(box, self, "selectedGroup", callback=self.onGroupSelection ) self.centerCombo = OWGUI.comboBox(self.controlArea, self, "selectedCenterMethod", box="Center Fold-change Using", items=[name for name, _ in self.CENTER_METHODS], callback=self.onCenterMethodChange, addSpace=True ) self.mergeCombo = OWGUI.comboBox(self.controlArea, self, "selectedMergeMethod", box="Merge Replicates", items=[name for name, _ in self.MERGE_METHODS], tooltip="Select the method for replicate merging", callback=self.onMergeMethodChange, addSpace=True ) box = OWGUI.doubleSpin(self.controlArea, self, "zCutoff", 0.0, 3.0, 0.01, box="Z-Score Cutoff", callback=[self.replotMA, self.commitIf]) OWGUI.separator(self.controlArea) box = OWGUI.widgetBox(self.controlArea, "Ouput") OWGUI.checkBox(box, self, "appendZScore", "Append Z-Scores", tooltip="Append calculated Z-Scores to output", callback=self.commitIf ) OWGUI.checkBox(box, self, "appendRIValues", "Append Log Ratio and Intensity values", tooltip="Append calculated Log Ratio and Intensity values to output data", callback=self.commitIf ) cb = OWGUI.checkBox(box, self, "autoCommit", "Commit on change", tooltip="Commit data on any change", callback=self.commitIf ) b = OWGUI.button(box, self, "Commit", callback=self.commit) OWGUI.setStopper(self, b, cb, "changedFlag", callback=self.commit) self.connect(self.graphButton, SIGNAL("clicked()"), self.saveGraph) OWGUI.rubber(self.controlArea) self.graph = OWGraph(self.mainArea) self.graph.setAxisTitle(QwtPlot.xBottom, "Intensity: log<sub>10</sub>(R*G)") self.graph.setAxisTitle(QwtPlot.yLeft, "Log ratio: log<sub>2</sub>(R/G)") self.graph.showFilledSymbols = True self.mainArea.layout().addWidget(self.graph) self.groups = [] self.split_data = None, None self.merged_splits = None, None self.centered = None, None self.changedFlag = False self.data = None self.resize(800, 600)
class OWMAPlot(OWWidget): settingsList = ["appendZScore", "appendRIValues"] contextHandlers = {"": DomainContextHandler("", ["selectedGroup", "zCutoff"])} CENTER_METHODS = [("Average", obiExpression.MA_center_average), ("Lowess (fast - interpolated)", obiExpression.MA_center_lowess_fast), ("Lowess", obiExpression.MA_center_lowess)] MERGE_METHODS = [("Average", numpy.ma.average), ("Median", numpy.ma.median), ("Geometric mean", obiExpression.geometric_mean)] def __init__(self, parent=None, signalManager=None, name="Normalize Expression Array"): OWWidget.__init__(self, parent, signalManager, name, wantGraph=True) self.inputs = [("Expression array", ExampleTable, self.setData)] self.outputs = [("Normalized expression array", ExampleTable, Default), ("Filtered expression array", ExampleTable)] self.selectedGroup = 0 self.selectedCenterMethod = 0 self.selectedMergeMethod = 0 self.zCutoff = 1.96 self.appendZScore = False self.appendRIValues = False self.autoCommit = False self.loadSettings() ## GUI self.infoBox = OWGUI.widgetLabel(OWGUI.widgetBox(self.controlArea, "Info", addSpace=True), "No data on input.") box = OWGUI.widgetBox(self.controlArea, "Split by", addSpace=True) self.groupCombo = OWGUI.comboBox(box, self, "selectedGroup", callback=self.onGroupSelection ) self.centerCombo = OWGUI.comboBox(self.controlArea, self, "selectedCenterMethod", box="Center Fold-change Using", items=[name for name, _ in self.CENTER_METHODS], callback=self.onCenterMethodChange, addSpace=True ) self.mergeCombo = OWGUI.comboBox(self.controlArea, self, "selectedMergeMethod", box="Merge Replicates", items=[name for name, _ in self.MERGE_METHODS], tooltip="Select the method for replicate merging", callback=self.onMergeMethodChange, addSpace=True ) box = OWGUI.doubleSpin(self.controlArea, self, "zCutoff", 0.0, 3.0, 0.01, box="Z-Score Cutoff", callback=[self.replotMA, self.commitIf]) OWGUI.separator(self.controlArea) box = OWGUI.widgetBox(self.controlArea, "Ouput") OWGUI.checkBox(box, self, "appendZScore", "Append Z-Scores", tooltip="Append calculated Z-Scores to output", callback=self.commitIf ) OWGUI.checkBox(box, self, "appendRIValues", "Append Log Ratio and Intensity values", tooltip="Append calculated Log Ratio and Intensity values to output data", callback=self.commitIf ) cb = OWGUI.checkBox(box, self, "autoCommit", "Commit on change", tooltip="Commit data on any change", callback=self.commitIf ) b = OWGUI.button(box, self, "Commit", callback=self.commit) OWGUI.setStopper(self, b, cb, "changedFlag", callback=self.commit) self.connect(self.graphButton, SIGNAL("clicked()"), self.saveGraph) OWGUI.rubber(self.controlArea) self.graph = OWGraph(self.mainArea) self.graph.setAxisTitle(QwtPlot.xBottom, "Intensity: log<sub>10</sub>(R*G)") self.graph.setAxisTitle(QwtPlot.yLeft, "Log ratio: log<sub>2</sub>(R/G)") self.graph.showFilledSymbols = True self.mainArea.layout().addWidget(self.graph) self.groups = [] self.split_data = None, None self.merged_splits = None, None self.centered = None, None self.changedFlag = False self.data = None self.resize(800, 600) def onFinished(self, status): self.setEnabled(True) def onUnhandledException(self, ex_info): self.setEnabled(True) print >> sys.stderr, "Unhandled exception in non GUI thread" ex_type, ex_val, tb = ex_info if ex_type == numpy.linalg.LinAlgError and False: self.error(0, "Linear algebra error: %s" % repr(ex_val)) else: sys.excepthook(*ex_info) def onGroupSelection(self): if self.data: self.updateInfoBox() self.splitData() self.runNormalization() def onCenterMethodChange(self): if self.data: self.runNormalization() def onMergeMethodChange(self): if self.data: self.splitData() self.runNormalization() def proposeGroups(self, data): col_labels = [attr.attributes.items() for attr in data.domain.attributes] col_labels = sorted(reduce(set.union, col_labels, set())) col_labels = [(key, value, 1) for key, value in col_labels] attrs = [attr for attr in data.domain.variables + data.domain.getmetas().values() \ if attr.varType == orange.VarTypes.Discrete] row_labels = [(attr.name, value, 0) for attr in attrs for value in attr.values] def filterSingleValues(labels): ret = [] for name, value, axis in labels: match = [(n, v, a) for n, v, a in labels if n == name] if len(match) > 1: ret.append((name, value, axis)) return ret col_labels = filterSingleValues(col_labels) row_labels = filterSingleValues(row_labels) return col_labels + row_labels def setData(self, data): self.closeContext("") self.data = data self.error([0 ,1]) if data is not None: self.infoBox.setText("%i genes on input" % len(data)) self.groups = self.proposeGroups(data) self.groupCombo.clear() self.groupCombo.addItems(["%s: %s" % (key, value) for key, value, axis in self.groups]) if not self.groups: self.error(1, "Input data has no class attribute or attribute labels!") self.clear() return self.openContext("", data) self.selectedGroup = min(self.selectedGroup, len(self.groups) - 1) self.updateInfoBox() self.splitData() self.runNormalization() else: self.clear() def clear(self): self.groups = [] self.data = None self.centered = None, None self.split_data = None, None self.merged_splits = None, None self.graph.removeDrawingCurves() self.infoBox.setText("No data on input") self.send("Normalized expression array", None) self.send("Filtered expression array", None) def updateInfoBox(self): genes = self.getGeneNames() self.infoBox.setText("%i genes on input" % len(self.data)) def getSelectedGroup(self): return self.groups[self.selectedGroup] def getSelectedGroupSplit(self): key, value, axis = self.getSelectedGroup() other_values = [v for k, v, a in self.groups if k == key and a == axis and v != value] return [(key, value), (key, other_values)], axis def getGeneNames(self): key, value, axis = self.getSelectedGroup() if axis == 0: genes = [str(ex[key]) for ex in self.data] else: genes = [attr.name for attr in self.data.domain.attributes] return genes def splitData(self): groups, axis = self.getSelectedGroupSplit() self.split_ind = [obiExpression.select_indices(self.data, key, value, axis) for key, value in groups] self.split_data = obiExpression.split_data(self.data, groups, axis) def getMerged(self): split1, split2 = self.split_data (array1, _, _), (array2, _, _) = split1.toNumpyMA(), split2.toNumpyMA() _, _, axis = self.getSelectedGroup() merge_function = self.MERGE_METHODS[self.selectedMergeMethod][1] merged1 = obiExpression.merge_replicates(array1, axis, merge_function=merge_function) merged2 = obiExpression.merge_replicates(array2, axis, merge_function=merge_function) self.merged_splits = merged1, merged2 return self.merged_splits def runNormalization(self): self.progressBarInit() self.progressBarSet(0.0) G, R = self.getMerged() self.progressBarSet(5.0) center_method = self.CENTER_METHODS[self.selectedCenterMethod][1] # TODO: progess bar , lowess can take a long time if self.selectedCenterMethod in [1, 2]: #Lowess Gc, Rc = center_method(G, R, f = 1./min(500., len(G)/100), iter=1) else: Gc, Rc = center_method(G, R) self.progressBarSet(70.0) self.centered = Gc, Rc self.z_scores = obiExpression.MA_zscore(Gc, Rc, 1./3.) self.progressBarSet(100.0) self.plotMA(Gc, Rc, self.z_scores, self.zCutoff) self.progressBarFinished() def runNormalizationAsync(self): """ Run MA centering and z_score estimation in a separate thread """ self.error(0) self.progressBarInit() self.progressBarSet(0.0) G, R = self.getMerged() # self.progressBarSet(5.0) center_method = self.CENTER_METHODS[self.selectedCenterMethod][1] use_lowess = self.selectedCenterMethod in [1, 2] def run(progressCallback = lambda value: None): # the function to run in a thread # progressCallback(5.0) if use_lowess: Gc, Rc = center_method(G, R, f=2./3., iter=1, progressCallback=lambda val: progressCallback(val/2)) else: Gc, Rc = center_method(G, R) progressCallback(50) z_scores = obiExpression.MA_zscore(Gc, Rc, 1./3., progressCallback= lambda val: progressCallback(50 + val/2)) return Gc, Rc, z_scores self.progressDiscard = ProgressBarDiscard(self, self) async = self.asyncCall(run, name="Normalization", onResult=self.onResults, onError=self.onUnhandledException) self.connect(async, SIGNAL("progressChanged(float)"), self.progressDiscard.progressBarSet, Qt.QueuedConnection) self.setEnabled(False) async.__call__(progressCallback=async.emitProgressChanged) ## comment out this line if threading creates any problems runNormalization = runNormalizationAsync def onResults(self, (Gc, Rc, z_scores)): """ Handle the results of centering and z-scoring """ assert(QThread.currentThread() is self.thread()) self.setEnabled(True) qApp.processEvents() self.progressBarFinished() self.centered = Gc, Rc self.z_scores = z_scores self.plotMA(Gc, Rc, z_scores, self.zCutoff) self.commit()