source: orange-bioinformatics/widgets/prototypes/OWANOVA.py @ 1073:7e12eb0dda7e

Revision 1073:7e12eb0dda7e, 29.2 KB checked in by markotoplak, 4 years ago (diff)

Anova for structured data format works with the current Qt.

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