source: orange-bioinformatics/_bioinformatics/widgets/prototypes/OWANOVA.py @ 1636:10d234fdadb9

Revision 1636:10d234fdadb9, 29.3 KB checked in by mitar, 2 years ago (diff)

Restructuring because we will not be using namespaces.

Line 
1## Automatically adapted for numpy.oldnumeric Oct 04, 2007 by
2
3"""
4<name>ANOVA</name>
5<description>Single Sample T-test, One/Two Way Analysis of Variance.</description>
6<icon>icons/ChipANOVA.png</icon>
7<priority>1070</priority>
8<contact>Peter Juvan (peter.juvan@fri.uni-lj.si)</contact>
9"""
10
11from __future__ import absolute_import
12
13import numpy.oldnumeric as Numeric, numpy.oldnumeric.ma as MA
14import scipy.stats
15
16from Orange.OrangeWidgets import OWGUI
17from Orange.OrangeWidgets.OWWidget import *
18
19from .. import Anova
20from .OWDataFiles import DataFiles, ExampleSelection
21
22class OWANOVA(OWWidget):
23    settingsList  = ["anovaType", "compareToValue", "_interaction", "selectorA", "selectorB", "selectorI", "alphaA", "alphaB", "alphaI", "autoUpdateSelName", "sendNotSelectedData", "sendProbabilities", "commitOnChange"]
24
25    def __init__(self, parent=None, signalManager = None):
26        OWWidget.__init__(self, parent, signalManager, 'ANOVA')
27        # input / output data: [("name1", [orange.ExampleTable1a,...]), ("name2", [orange.ExampleTable2a,...])]
28        self.inputs = [("Structured Data", DataFiles, self.onDataInput)]
29        self.outputs = [("Example Selection", ExampleSelection, Default), ("Selected Structured Data", DataFiles, Default), ("Other Structured Data", DataFiles)]
30
31        # data, p-values, selected examples
32        self.dataStructure = None   # input data
33        self.numExamples = 0
34        self.numVariables = 0
35        self.ps = None              # p-values: 2D Numeric.array of shape (3, numExamples)
36        self.selectorName = ""      # for Example Selection output: (self.selectorName, [0,1,0,...])
37
38        # Settings
39        self.anovaType = 0      # 0: single-sample t-test, 1: one-way (A), 2: one-way (B), 3: two-way (A,B), 4: ful factorial (A, B, A*B)
40        self.compareToValue = 0 # single sample t-test, value to compare to
41        self._interaction = 0    # 0: no interaction, 1: test for interaction effect (set this value manually !!!)
42        self.selectorA = True
43        self.selectorB = False
44        self.selectorI = False
45        self.alphaA = "0.05"
46        self.alphaB = "0.05"
47        self.alphaI = "0.05"
48        self.autoUpdateSelName = 1
49        self.sendNotSelectedData = 1
50        self.sendProbabilities = 0
51        self.commitOnChange = 0
52        self.loadSettings()
53
54        # GUI
55        self.mainArea.setFixedWidth(0)
56        ca = self.controlArea
57       
58        # info
59        box = OWGUI.widgetBox(ca, "Info")
60        #gl.addWidget(box,0,0)
61        self.infoa = OWGUI.label(box, self, 'No data on input.')
62        self.infob = OWGUI.label(box, self, "")
63        self.infoc = OWGUI.label(box, self, "")
64
65        # ANOVA type
66        # group selection
67        anovaTypes = ["Single sample t-test", 
68            "Single-factor (A, variables)", 
69            "Single-factor (B, data sets)", 
70            "Two-factor", 
71            "Two-factor with interaction effect"]
72
73        self.boxAnovaType = OWGUI.widgetBox(ca, "Anova Type")
74        self.anovaTypeS = OWGUI.radioButtonsInBox(self.boxAnovaType, self, "anovaType", btnLabels=anovaTypes)
75       
76        self.boxAnovaType.setDisabled(1)
77
78        self.boxCompareTo = OWGUI.widgetBox(self.boxAnovaType)
79        OWGUI.lineEdit(self.boxCompareTo, self, "compareToValue", callback=self.onCompareToChange, label="compare to")
80
81        # selection of examples
82        self.boxSelection = OWGUI.widgetBox(ca, "Example Selection")
83        self.lblNumGenes = []   # list of labels
84
85        # selector A
86        self.boxSelectorA = OWGUI.widgetBox(self.boxSelection)
87        self.cbSelectorA = OWGUI.checkBox(self.boxSelectorA, self, "selectorA", "Factor A (variables)", callback=self.onSelectionChange,
88                                          tooltip='H0: The mean does not depend on factor A (represented by variables).')
89
90        frmA = OWGUI.widgetBox(self.boxSelectorA)
91        leA = OWGUI.lineEdit(frmA, self, "alphaA", orientation="horizontal", callback=lambda x=0: self.onAlphaChange(x), label= "p <= ")
92        self.lblNumGenes.append(OWGUI.label(frmA, self, ""))
93
94        # selector B
95        self.boxSelectorB = OWGUI.widgetBox(self.boxSelection)
96        self.cbSelectorB = OWGUI.checkBox(self.boxSelectorB, self, "selectorB", "Factor B (data sets)", callback=self.onSelectionChange,
97                                          tooltip='H0: The mean does not depend on factor B (represented by data sets).')
98 
99        frmB = OWGUI.widgetBox(self.boxSelectorB)
100        leB = OWGUI.lineEdit(frmB, self, "alphaB", orientation="horizontal", callback=lambda x=1: self.onAlphaChange(x), label= "p <= ")
101        self.lblNumGenes.append(OWGUI.label(frmB, self, ""))
102
103        # selector I
104        self.boxSelectorI = OWGUI.widgetBox(self.boxSelection)
105        self.cbSelectorI = OWGUI.checkBox(self.boxSelectorI, self, "selectorI", "Interaction (variables * data sets)", callback=self.onSelectionChange,
106                                          tooltip='H0: There is no interaction between factor A and factor B.')
107 
108        frmI = OWGUI.widgetBox(self.boxSelectorI)
109        leI = OWGUI.lineEdit(frmI, self, "alphaI", orientation="horizontal", callback=lambda x=2: self.onAlphaChange(x), label= "p <= ")
110        self.lblNumGenes.append(OWGUI.label(frmI, self, ""))
111
112        # output
113        box = OWGUI.widgetBox(ca, "Output")
114        self.leSelectorName = OWGUI.lineEdit(box, self, 'selectorName', label='Selector Name: ')
115        self.leSelectorName.setReadOnly(self.autoUpdateSelName)
116        OWGUI.checkBox(box, self, 'autoUpdateSelName', 'Automatically update selector name', callback=self.onAutoUpdateSelNameChange)
117        OWGUI.checkBox(box, self, 'sendNotSelectedData', 'Send not selected data', callback=self.onSendNotSelectedChange)
118        OWGUI.checkBox(box, self, 'sendProbabilities', 'Show p-values', callback=self.onSendProbabilitiesChange)
119        OWGUI.checkBox(box, self, 'commitOnChange', 'Commit data on selection change', callback=lambda: self.onCommit(self.commitOnChange))
120        self.btnCommit = OWGUI.button(box, self, "Commit", callback=self.onCommit)
121
122        # enable/disable anova type box, example selection box, commit button, update the number of examples for individual selectors
123        self.updateAnovaTypeBox()
124        self.updateSelectorBox()
125        self.updateSelectorInfos()
126        self.updateSelectorName()
127
128        self.resize(283, self.sizeHint().height())
129
130
131    def onDataInput(self, structuredData):
132        """handles input data; sets self.dataStructure, self.numExamples, self.numVariables and self.ps;
133        updates info, calls updateAnovaTypeBox(), runs ANOVA and sends out new data.
134        """
135        self.dataStructure = structuredData
136        self.numExamples = 0
137        self.numVariables = 0
138        self.ps = None
139        if structuredData:
140            numFiles = reduce(lambda a,b: a+len(b[1]), structuredData, 0)
141            lenSD = len(structuredData)
142            self.infoa.setText("%d set%s, total of %d data file%s." % (lenSD, ["","s"][lenSD!=1], numFiles, ["","s"][numFiles!=1]))
143            numExamplesList = []
144            numVariablesList = []
145            # construct a list of ExampleTable lengths and a list of number of variables
146            for (name, etList) in structuredData:
147                for et in etList:
148                    numExamplesList.append(len(et))
149                    numVariablesList.append(len(et.domain.variables))
150            # test that all ExampleTables consist of equal number of examples and variables
151            if len(numExamplesList) == 0 or Numeric.add.reduce(Numeric.equal(numExamplesList, numExamplesList[0])) != len(numExamplesList):
152                self.dataStructure = None
153                self.numExamples = -1
154                self.infob.setText("Error: data files contain unequal number of examples, aborting ANOVA computation.")
155                self.infoc.setText('')
156            elif len(numVariablesList) == 0 or Numeric.add.reduce(Numeric.equal(numVariablesList, numVariablesList[0])) != len(numVariablesList):
157                self.dataStructure = None
158                self.numVariables = -1
159                self.infob.setText("Error: data files contain unequal number of variables, aborting ANOVA computation.")
160                self.infoc.setText('')
161            else:
162                self.numExamples = numExamplesList[0]
163                self.numVariables = numVariablesList[0]
164                self.infob.setText("%d variable%s, %d example%s in each file." % (self.numVariables, ["","s"][self.numVariables!=1], self.numExamples, ["","s"][self.numExamples!=1]))
165                if self.numExamples > 0:
166                    self.infoc.setText('Press Commit button to start ANOVA computation.')
167                else:
168                    self.infoc.setText('')
169                self.boxAnovaType.setEnabled(1)
170                self.boxSelection.setEnabled(1)
171                self.btnCommit.setEnabled(True)
172        else:
173            self.infoa.setText('No data on input.')
174            self.infob.setText('')
175            self.infoc.setText('')
176        # enable/disable anova type selection depending on the type of input data
177        self.updateAnovaTypeBox()
178        self.updateSelectorBox()
179        if self.autoUpdateSelName:
180            self.updateSelectorName()
181        # run ANOVA
182        if self.commitOnChange:
183            self.runANOVA()
184            self.senddata()
185        self.updateSelectorInfos()
186
187       
188    def runANOVA(self):
189        """converts structured data [(name, [orngET1, orngET2, ...]),...] to a 3D masked array
190        with the following axes: 0: examples, 1: variables, 2: ExampleTables;
191        runs ANOVA computations and sets self.ps;
192        """
193        if self.dataStructure and self.numExamples > 0:
194            ma3d = MA.zeros((self.numExamples, self.numVariables, reduce(lambda a,b: a+len(b[1]), self.dataStructure, 0)), Numeric.Float) * MA.masked
195            groupLens = []
196            etIdx = 0
197            for dsName, etList in self.dataStructure:
198                for et in etList:
199                    ma3d[:,:,etIdx] = et.toNumpyMA("ac")[0]
200                    etIdx += 1
201                groupLens.append(len(etList))
202
203            #print "ma3d SHAPE", ma3d.shape
204            #print "ma3d from top", ma3d[0,:,:]
205            # run ANOVA
206            self.infoc.setText('ANOVA computation started...')
207            self.progressBarInit()
208            pbStep = 100./self.numExamples
209            self.ps = Numeric.ones((3, self.numExamples), Numeric.Float)
210            if self.anovaType >= 3:
211                ps = self.anova2(ma3d, groupLens, self.anovaType==4, repMeasuresOnA=False, callback=lambda: self.progressBarAdvance(pbStep))
212                for rIdx in range(ps.shape[0]):
213                    self.ps[rIdx] = ps[rIdx]
214            elif self.anovaType == 2:
215                self.ps[1] = self.anova1B(ma3d, groupLens, repMeasures=False, callback=lambda: self.progressBarAdvance(pbStep))
216            elif self.anovaType == 1:
217                self.ps[0] = self.anova1A(ma3d, repMeasures=False, callback=lambda: self.progressBarAdvance(pbStep))
218            elif self.anovaType == 0:
219                try:
220                    compToVal = float(self.compareToValue)
221                except:
222                    print "Warning: cannot convert %s to float, using 0" % str(self.compareToValue)
223                    self.compareToValue = 0
224                    compToVal = 0
225                self.ps[0] = self.ttest_ssmpl(ma3d, compToVal, callback=lambda: self.progressBarAdvance(pbStep))
226            self.progressBarFinished()
227
228
229    def ttest_ssmpl(self, ma3d, compToVal, callback):
230        """conducts single-sample t-test on individual examples wrt factor A (variables, ma3d axis 1);
231        returns Numeric array of p-values in shape (1, numExamples).
232        """
233        ps = -1*Numeric.ones((ma3d.shape[0],), Numeric.Float)
234        for eIdx in range(ma3d.shape[0]):
235            data = Numeric.asarray(MA.transpose(ma3d[eIdx]).compressed())
236            if len(data) >= 2:
237                try:
238                    ps[eIdx] = scipy.stats.ttest_1samp(data, compToVal)[1]
239                except:
240                    print "Warning: zero variance, check the example %i:" % eIdx, data
241                    ps[eIdx] = 1.0
242            else:
243                ps[eIdx] = 1.0
244            callback()
245        return ps
246
247    def anova1A(self, ma3d, repMeasures, callback):
248        """conducts one-way ANOVA on individual examples wrt factor A (variables, ma3d axis 1);
249        returns Numeric array of p-values in shape (1, numExamples).
250        """
251        ps = -1*Numeric.ones((ma3d.shape[0],), Numeric.Float)
252        if repMeasures:
253            fAnova = Anova.AnovaRM12LR
254        else:
255            fAnova = Anova.Anova1wayLR_2D
256        for eIdx in range(ma3d.shape[0]):
257            an = fAnova(MA.transpose(ma3d[eIdx]))
258            ps[eIdx] = an.Fprob
259            callback()
260        return ps
261
262    def anova1B(self, ma3d, groupLens, repMeasures, callback):
263        """conducts one-way ANOVA on individual examples wrt factor B (data sets);
264        ma3d axis 2 also contains replicas according to groupLens;
265        returns Numeric array of p-values in shape (1, numExamples).
266        WARNING: works slower than anova1A because it requires to copy 1D array to 2D array
267                 although we could use Anova1wayLR instead of Anova1wayLR_2D, but not for repeated measures
268                 additionaly, Anova1wayLR_2D handles missing factor levels correctly, which is not the case for Anova1wayLR
269        """
270        ps = -1*Numeric.ones((ma3d.shape[0],), Numeric.Float)
271        # groupLens [2,3,4] -> groupInd [[0,1],[2,3,4],[5,6,7,8]]
272        if repMeasures:
273            fAnova = Anova.AnovaRM12LR
274        else:
275            fAnova = Anova.Anova1wayLR_2D
276        grpLensAcc = Numeric.concatenate([[0],Numeric.add.accumulate(groupLens)])
277        grpInd = map(lambda i,j: range(i, j), grpLensAcc[:-1], grpLensAcc[1:])
278        for eIdx in range(ma3d.shape[0]):
279            m2 = MA.zeros((max(groupLens)*ma3d.shape[1], len(groupLens)), Numeric.Float) * MA.masked # axis0: replicas, axis1: factor B levels
280            for groupIdx,takeInd in enumerate(grpInd):
281                m2[:groupLens[groupIdx]*ma3d.shape[1], groupIdx] = MA.ravel(ma3d[eIdx].take(takeInd, 1))
282            an = fAnova(m2)
283            ps[eIdx] = an.Fprob
284            callback()
285        return ps
286
287    def anova2(self, ma3d, groupLens, addInteraction, repMeasuresOnA, callback):
288        """Conducts two-way ANOVA on individual examples;
289        returns a Numeric array of p-values in shape (2, numExamples) or (3, numExamples), depending whether we test for interaction;
290        Note: levels of factors A and B that cause empty cells are removed prior to conducting ANOVA.
291        """
292        groupLens = Numeric.asarray(groupLens)
293        # arrays to store p-vals
294        if addInteraction:
295            ps = Numeric.ones((3, ma3d.shape[0]), Numeric.Float)
296        else:
297            ps = Numeric.ones((2, ma3d.shape[0]), Numeric.Float)
298        # decide between non-repeated / repeated measures ANOVA for factor time
299        if repMeasuresOnA:
300            fAnova = Anova.AnovaRM12LR
301        else:
302            fAnova = Anova.Anova2wayLR
303        # check for empty cells for all genes at once and remove them
304        tInd2rem = []
305        ax2Ind = Numeric.concatenate(([0], Numeric.add.accumulate(groupLens)))
306        for aIdx in range(ma3d.shape[1]):
307            for rIdx in range(groupLens.shape[0]):
308                if Numeric.add.reduce(MA.count(ma3d[:,aIdx,ax2Ind[rIdx]:ax2Ind[rIdx+1]],1)) == 0:
309                    tInd2rem.append(aIdx)
310                    break
311        if len(tInd2rem) > 0:
312            print "Warning: removing time indices %s for all genes" % (str(tInd2rem))
313            tInd2keep = range(ma3d.shape[1])
314            for aIdx in tInd2rem:
315                tInd2keep.remove(aIdx)
316            ma3d = ma3d.take(tInd2keep, 1)
317        # for each gene...
318        for eIdx in range(ma3d.shape[0]):
319            # faster check for empty cells for that gene -> remove time indices with empty cells
320            ma2d = ma3d[eIdx]
321            cellCount = MA.zeros((ma2d.shape[0], groupLens.shape[0]), Numeric.Int)
322            for g,(i0,i1) in enumerate(zip(ax2Ind[:-1], ax2Ind[1:])):
323                cellCount[:,g] = MA.count(ma2d[:,i0:i1], 1)
324            ma2dTakeInd = Numeric.logical_not(Numeric.add.reduce(Numeric.equal(cellCount,0),1)) # 1 where to take, 0 where not to take
325            if Numeric.add.reduce(ma2dTakeInd) != ma2dTakeInd.shape[0]:
326                print "Warning: removing time indices %s for gene %i" % (str(Numeric.compress(ma2dTakeInd == 0, Numeric.arange(ma2dTakeInd.shape[0]))), eIdx)
327                ma2d = MA.compress(ma2dTakeInd, ma2d, 0)
328            an = fAnova(ma2d, groupLens, addInteraction, allowReductA=True, allowReductB=True)
329            ps[:,eIdx] = an.ps
330            callback()
331        return ps
332
333
334    def updateAnovaTypeBox(self):
335        """enables/disables: - anova type selection box;
336                             - example selection box;
337                             - selectors A, B and I
338                             - Commit button
339        """
340        if self.dataStructure and self.numExamples > 0:
341            # enable anova type box and commit button
342            self.boxAnovaType.setEnabled(1)
343            self.btnCommit.setEnabled(1)
344            # select appropriate anova type
345            if len(self.dataStructure) == 1 and self.numVariables == 1:
346                # single-sample t-test (factor A)
347                self.anovaType = 0
348            elif len(self.dataStructure) == 1 and self.numVariables > 1:
349                # single-factor (A) ANOVA
350                self.anovaType = 1
351            elif len(self.dataStructure) > 1 and self.numVariables == 1:
352                # single-factor (B) ANOVA
353                self.anovaType = 2
354            elif len(self.dataStructure) > 1 and self.numVariables > 1:
355                # two-factor ANOVA
356                self.anovaType = int(self._interaction) + 3
357            # enable/disable appropriate anova type radio buttons
358            if self.anovaType <= 2:
359                for i in range(5):
360                    self.boxAnovaType.buttons[i].setEnabled(self.anovaType == i)
361            else:
362                self.boxAnovaType.buttons[0].setEnabled(0)
363                for i in range(1,5):
364                    self.boxAnovaType.buttons[i].setEnabled(1)
365            # enable/disable compareTo lineEdit
366            self.boxCompareTo.setEnabled(self.anovaType == 0)
367        else:
368            # disable anova type box and commit button
369            self.boxAnovaType.setDisabled(1)
370            self.btnCommit.setDisabled(1)
371
372
373    def updateSelectorBox(self):
374        """enables / disables individual selectors
375        """
376        if self.dataStructure and self.numExamples > 0:
377            # enable example selection box
378            self.boxSelection.setEnabled(1)
379            # enable/disable selectors A, B and I
380            self.boxSelectorA.setEnabled(self.anovaType != 2)
381            self.boxSelectorB.setEnabled(self.anovaType >= 2)
382            self.boxSelectorI.setEnabled(self.anovaType == 4)
383        else:
384            # disable example selection box
385            self.boxSelection.setDisabled(1)
386
387
388    def updateSelectorInfos(self, selectorIdx=None):
389        """updates the number of examples that match individual selectors;
390        if selectorIdx is given, updates only the corresponding info.
391        """
392        if not selectorIdx:
393            selectorInd = range(3)
394        else:
395            selectorInd = [selectorIdx]
396        alphas = [self.alphaA, self.alphaB, self.alphaI]
397        for si in selectorInd:
398            try:
399                alpha = float(alphas[si])
400                ps = self.ps[si]
401            except:
402                alpha = None
403                ps = None
404            if ps != None and alpha != None and self.anovaType in [[0,1,3,4],[2,3,4],[4]][si]:
405                numSelected = Numeric.add.reduce(Numeric.less_equal(self.ps[si], alpha))
406                self.lblNumGenes[si].setText('  (%d example%s)' % (numSelected, ['', 's'][numSelected!=1]))
407            else:
408                self.lblNumGenes[si].setText('  (no examples)')
409
410
411    def senddata(self):
412        """computes selectionList, partitions the examples and updates infoc;
413        sends out selectionList and selected/other dataStructure or None;
414        """
415##        if self.dataStructure and self.ps:
416        if self.dataStructure and self.ps.shape[1]:
417            # set selectionList
418            alphas = [self.alphaA, self.alphaB, self.alphaI]
419            selectors = [self.selectorA, self.selectorB, self.selectorI]
420            selectionList = Numeric.ones((self.numExamples,))
421            for si in range(3):
422                try:
423                    if selectors[si] and self.anovaType in [[0,1,3,4],[2,3,4],[4]][si]:
424                        selectionList = Numeric.logical_and(selectionList, Numeric.less_equal(self.ps[si], float(alphas[si])))
425                except:
426                    pass
427            self.infoc.setText('Sending out data...')
428           
429            if self.sendProbabilities:
430                # create example table with probabilities
431                print self.ps
432                print Numeric.transpose(self.ps).shape
433                etProb = orange.ExampleTable(orange.Domain([orange.FloatVariable("Factor A p-val"),orange.FloatVariable("Factor B p-val"),orange.FloatVariable("Interaction p-val")]), Numeric.transpose(self.ps))
434                # in etProb, convert p-val to meta attribute
435                domProb = orange.Domain([])
436                domProb.addmetas(dict(zip([orange.newmetaid(),orange.newmetaid(),orange.newmetaid()], etProb.domain.variables)))
437                etProb = orange.ExampleTable(domProb, etProb)
438            else:
439                # create new etProb without attributes/metas and of length equal to etProb
440                etProb = orange.ExampleTable(orange.Domain([]), Numeric.zeros((selectionList.shape[0],0)))
441
442            # partition dataStructure and send out data
443            selectionList = selectionList.tolist()
444            self.send("Example Selection", (self.selectorName, selectionList))
445            dataStructS = []
446            dataStructN = []
447            self.progressBarInit()
448
449            if self.sendNotSelectedData:
450                pbStep = 50./len(self.dataStructure)
451            else:
452                pbStep = 100./len(self.dataStructure)
453
454            for (dsName, etList) in self.dataStructure:
455                etListS = [et.select(selectionList) for et in etList]
456                for i in range(len(etList)):
457                    # append probabilities (if etProb not empty)
458                    etListS[i] = orange.ExampleTable([etListS[i], etProb.select(selectionList)])
459                    # add name
460                    etListS[i].name = etList[i].name
461                dataStructS.append((dsName, etListS))
462                self.progressBarAdvance(pbStep)
463            self.send("Selected Structured Data", dataStructS)
464
465            if self.sendNotSelectedData:
466                for (dsName, etList) in self.dataStructure:
467                    etListN = [et.select(selectionList, negate=1) for et in etList]
468                    for i in range(len(etList)):
469                        # append probabilities (if etProb not empty)
470                        etListN[i] = orange.ExampleTable([etListN[i], etProb.select(selectionList, negate=1)])
471                        # add name
472                        etListN[i].name = etList[i].name
473                    dataStructN.append((dsName, etListN))
474                    self.progressBarAdvance(pbStep)
475                self.send("Other Structured Data", dataStructN)
476            else:
477                self.send("Other Structured Data", None)
478
479            self.progressBarFinished()
480            # report the number of selected examples
481            numExamples = Numeric.add.reduce(Numeric.greater(selectionList, 0))
482            self.infoc.setText('Total of %d example%s match criteria.' % (numExamples, ['', 's'][numExamples!=1]))
483        else:
484            self.send("Example Selection", None)
485            self.send("Selected Structured Data", None)
486            self.send("Other Structured Data", None)
487           
488
489    def updateSelectorName(self):
490        """update selector name shown in selector edit box
491        """
492        if self.dataStructure:
493            if self.anovaType == 0:
494                s = '1 smpl. t-test, compared to %s' % self.compareToValue
495            else:
496                s = 'ANOVA'
497            s += " (%s)" % reduce(lambda a,b: a + ", " + b[0], self.dataStructure, "")[2:]
498            if self.selectorA and self.anovaType in [0,1,3,4]:
499                s += ", pA<%s" % self.alphaA
500            if self.selectorB and self.anovaType in [2,3,4]:
501                s += ", pB<%s" % self.alphaB
502            if self.selectorI and self.anovaType == 4:
503                s += ", pI<%s" % self.alphaI
504            self.selectorName = s.strip()
505        else:
506            self.selectorName = ""
507
508
509    #==========================================================================
510    # Event handlers
511    #==========================================================================
512
513    def onCompareToChange(self):
514        """handles changes of ANOVA type:
515            - resets self.ps;
516            - updates infoc
517            - calls updateSelectorInfos()
518        runs ANOVA and sends out new data;
519        """
520        if self.anovaType == 0:
521            self.ps = None
522            if self.autoUpdateSelName:
523                self.updateSelectorName()
524            if self.commitOnChange:
525                self.runANOVA()
526                self.senddata()
527            elif self.dataStructure and self.numExamples > 0:
528                self.infoc.setText('Press Commit button to start ANOVA computation.')
529            self.updateSelectorInfos()
530
531
532    def onAnovaType(self):
533        """handles changes of ANOVA type:
534            - resets self.ps;
535            - calls updateSelectorBox()
536            - updates infoc
537            - calls updateSelectorInfos()
538        runs ANOVA and sends out new data;
539        """
540        #print "self.anovaType", self.anovaType
541        self._interaction = self.anovaType == 4
542        self.ps = None
543        self.updateSelectorBox()
544        if self.autoUpdateSelName:
545            self.updateSelectorName()
546        if self.commitOnChange:
547            self.runANOVA()
548            self.senddata()
549        elif self.dataStructure and self.numExamples > 0:
550            self.infoc.setText('Press Commit button to start ANOVA computation.')
551        self.updateSelectorInfos()
552
553
554    def onInteraction(self):
555        """handles clicks on interaction checkbox:
556            - resets self.ps;
557            - enables/disables selector I,
558            - updates infoc
559        runs ANOVA and sends out new data
560        """
561        self.ps = None
562        self.boxSelectorI.setEnabled(self.interaction)
563        if self.autoUpdateSelName:
564            self.updateSelectorName()
565        if self.commitOnChange:
566            self.runANOVA()
567            self.senddata()
568        elif self.dataStructure and self.numExamples > 0:
569            self.infoc.setText('Press Commit button to start ANOVA computation.')
570        self.updateSelectorInfos()
571
572
573    def onSelectionChange(self):
574        """handles changes in example selector checkboxes;
575        sends out new data;
576        """
577        if self.autoUpdateSelName:
578            self.updateSelectorName()
579        if self.commitOnChange:
580            self.senddata()
581
582
583    def onAlphaChange(self, selectorIdx):
584        """handles changes in example selector alphas;
585        prints number of selected examples for individual selectors and sends out new data;
586        """
587        if self.autoUpdateSelName:
588            self.updateSelectorName()
589        if self.commitOnChange:
590            self.senddata()
591        self.updateSelectorInfos(selectorIdx)
592
593
594    def onAutoUpdateSelNameChange(self):
595        """handles clicks on auto update selector name checkbox
596        """
597        self.leSelectorName.setReadOnly(self.autoUpdateSelName)
598
599           
600    def onSendNotSelectedChange(self):
601        """handles clicks on sendNotSelectedData checkbox
602        """
603        if self.commitOnChange:
604            self.senddata()
605
606    def onSendProbabilitiesChange(self):           
607        """handles clicks on show p-values checkbox
608        """
609        if self.commitOnChange:
610            self.senddata()
611           
612    def onCommit(self, commit=True):
613        """handles Commit clicks; runs ANOVA (if not already computed) and sends out data;
614        """
615        if commit:
616            if self.dataStructure:
617                if self.ps == None:
618                    self.runANOVA()
619                self.senddata()
620            self.updateSelectorInfos()
621
622
623if __name__=="__main__":
624    from . import OWDataFiles, OWDataFilesSelector
625    from Orange.orng import orngSignalManager
626    from Orange.OrangeWidgets.Data import OWDataTable
627
628    signalManager = orngSignalManager.SignalManager(0)
629    a=QApplication(sys.argv)
630    an=OWANOVA(signalManager = signalManager)
631
632    an.show()
633   
634    df = OWDataFiles.OWDataFiles(signalManager = signalManager)
635    df.loadData("/home/marko/anova/smallchipdata")
636    df.show()
637
638    signalManager.addWidget(an)
639    signalManager.addWidget(df)
640    signalManager.setFreeze(1)
641    signalManager.addLink(df, an, 'Structured Data', 'Structured Data', 1)
642
643    # data files selector, data table
644    dfs = OWDataFilesSelector.OWDataFilesSelector(signalManager = signalManager)
645    signalManager.addWidget(dfs)
646    dfs.show()
647    signalManager.addLink(an, dfs, 'Selected Structured Data', 'Structured Data', 1)
648    dt = OWDataTable.OWDataTable(signalManager = signalManager)
649    signalManager.addWidget(dt)
650    signalManager.addLink(dfs, dt, 'Examples', 'Examples', 1)
651    signalManager.setFreeze(0)
652    dt.show()
653
654    a.exec_()
655    an.saveSettings()
Note: See TracBrowser for help on using the repository browser.