Example #1
0
    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)
Example #2
0
    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)
Example #3
0
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()
Example #4
0
    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)
Example #5
0
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()
Example #6
0
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()
Example #7
0
 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)
Example #8
0
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()