#
source:
orange-bioinformatics/_bioinformatics/widgets/prototypes/OWANOVA.py
@
1643:2cfa80dac3d3

Revision 1643:2cfa80dac3d3, 29.4 KB checked in by mitar, 2 years ago (diff) |
---|

Rev | Line | |
---|---|---|

[972] | 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> | |

[1643] | 9 | <prototype>1</prototype> |

[972] | 10 | """ |

11 | ||

[1633] | 12 | from __future__ import absolute_import |

13 | ||

[972] | 14 | import numpy.oldnumeric as Numeric, numpy.oldnumeric.ma as MA |

[1633] | 15 | import scipy.stats |

[1073] | 16 | |

[1633] | 17 | from Orange.OrangeWidgets import OWGUI |

18 | from Orange.OrangeWidgets.OWWidget import * | |

[972] | 19 | |

[1633] | 20 | from .. import Anova |

21 | from .OWDataFiles import DataFiles, ExampleSelection | |

[972] | 22 | |

23 | class 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) | |

[1073] | 57 | ca = self.controlArea |

58 | ||

[972] | 59 | # info |

[1073] | 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, "") | |

[972] | 65 | |

66 | # ANOVA type | |

[1073] | 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 | ||

[972] | 77 | self.boxAnovaType.setDisabled(1) |

78 | ||

[1073] | 79 | self.boxCompareTo = OWGUI.widgetBox(self.boxAnovaType) |

80 | OWGUI.lineEdit(self.boxCompareTo, self, "compareToValue", callback=self.onCompareToChange, label="compare to") | |

81 | ||

[972] | 82 | # selection of examples |

[1073] | 83 | self.boxSelection = OWGUI.widgetBox(ca, "Example Selection") |

[972] | 84 | self.lblNumGenes = [] # list of labels |

[1073] | 85 | |

[972] | 86 | # selector A |

[1073] | 87 | self.boxSelectorA = OWGUI.widgetBox(self.boxSelection) |

[972] | 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).') | |

[1073] | 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, "")) | |

[972] | 94 | |

95 | # selector B | |

[1073] | 96 | self.boxSelectorB = OWGUI.widgetBox(self.boxSelection) |

[972] | 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).') | |

[1073] | 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 | ||

[972] | 104 | # selector I |

[1073] | 105 | self.boxSelectorI = OWGUI.widgetBox(self.boxSelection) |

[972] | 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.') | |

[1073] | 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 | ||

[972] | 113 | # output |

[1073] | 114 | box = OWGUI.widgetBox(ca, "Output") |

[972] | 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() | |

[1073] | 128 | |

[972] | 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)) | |

[1073] | 203 | |

204 | #print "ma3d SHAPE", ma3d.shape | |

205 | #print "ma3d from top", ma3d[0,:,:] | |

[972] | 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 | """ | |

[1073] | 541 | #print "self.anovaType", self.anovaType |

[972] | 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: | |

[1073] | 618 | if self.ps == None: |

[972] | 619 | self.runANOVA() |

620 | self.senddata() | |

621 | self.updateSelectorInfos() | |

622 | ||

623 | ||

624 | if __name__=="__main__": | |

[1633] | 625 | from . import OWDataFiles, OWDataFilesSelector |

626 | from Orange.orng import orngSignalManager | |

627 | from Orange.OrangeWidgets.Data import OWDataTable | |

[1073] | 628 | |

[972] | 629 | signalManager = orngSignalManager.SignalManager(0) |

630 | a=QApplication(sys.argv) | |

631 | an=OWANOVA(signalManager = signalManager) | |

[1073] | 632 | |

[972] | 633 | an.show() |

[1073] | 634 | |

[972] | 635 | df = OWDataFiles.OWDataFiles(signalManager = signalManager) |

[1073] | 636 | df.loadData("/home/marko/anova/smallchipdata") |

637 | df.show() | |

[972] | 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) | |

[1073] | 647 | dfs.show() |

[972] | 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 | ||

[1073] | 655 | a.exec_() |

[972] | 656 | an.saveSettings() |

**Note:**See TracBrowser for help on using the repository browser.