source: orange-bioinformatics/orangecontrib/bio/widgets/prototypes/OWANOVA.py @ 1873:0810c5708cc5

Revision 1873:0810c5708cc5, 29.4 KB checked in by Ales Erjavec <ales.erjavec@…>, 6 months ago (diff)

Moved '_bioinformatics' into orangecontrib namespace.

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