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

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

Restructuring because we will not be using namespaces.

Line 
1## Automatically adapted for numpy.oldnumeric Oct 04, 2007 by
2
3"""
4<name>Impute Profiles</name>
5<description>Imputation and non-parametric smoothing of expression profiles.</description>
6<icon>icons/ImputeProfiles.png</icon>
7<priority>1065</priority>
8<contact>Peter Juvan (peter.juvan@fri.uni-lj.si)</contact>
9"""
10
11import math
12
13import numpy.oldnumeric as Numeric, numpy.oldnumeric.ma as MA
14
15from Orange.OrangeWidgets import OWGUI
16from Orange.OrangeWidgets.OWWidget import *
17
18from .. import chipimpute, chipstat
19from .OWDataFiles import DataFiles
20
21class OWImputeProfiles(OWWidget):
22    settingsList  = ['impute', 'imputeK', 'smooth', 'windowSize', 'commitOnChange']
23
24    def __init__(self, parent=None, signalManager = None):
25        self.callbackDeposit = [] # deposit for OWGUI callback functions
26        OWWidget.__init__(self, parent, signalManager, 'Impute & Loess Profiles')
27
28        self._data = None       # exampleTable
29        self._dataMA = None     # input 2d masked array
30        self._chipdata = None   # [(dirname0, [et0, et1, ...]), ...]
31        self._chipdataMA = []   # [(dirname0, [m2d0, m2d1, ...]), ...]
32        self.impute = 1
33        self.imputeK = 20
34        self.smooth = 1
35        self.windowSize = 3
36        self.commitOnChange = 1
37               
38        # Settings
39        self.loadSettings()
40
41        # GUI
42        self.mainArea.setFixedWidth(0)
43        ca=QFrame(self.controlArea)
44        gl=QGridLayout(ca,4,1,5)
45        # info
46        box = QVGroupBox("Info", ca)
47        gl.addWidget(box, 0,0)
48        self.infoa = QLabel("No examples on input", box)
49        self.infob = QLabel("", box)
50        QLabel("", box)
51        self.infoc = QLabel("No structured data on input", box)
52        self.infod = QLabel("", box)
53        # KNN impute
54        self.boxImpute = QVGroupBox("Impute missing values", ca)
55        gl.addWidget(self.boxImpute, 1,0)
56        OWGUI.checkBox(self.boxImpute, self, "impute", "KNN impute", tooltip="Impute missing values from values of K nearest neighbours.", callback=self.change)
57##        self.sliderK = OWGUI.hSlider(self.boxImpute, self, "imputeK", box=None, minValue=1, maxValue=7744, step=1, callback=self.imputeChange, labelFormat=" K = %i", ticks=0)
58##        self.sliderK = OWGUI.qwtHSlider(self.boxImpute, self, "imputeK", box=None, label="K", labelWidth=12, minValue=1, maxValue=7744, step=0.02, precision=0, callback=self.imputeChange, logarithmic=1, ticks=0, maxWidth=200)
59##        self.sliderK = OWGUI.qwtHSlider(self.boxImpute, self, "imputeK", box=None, label="K", labelWidth=12, minValue=1, maxValue=100, step=1, precision=0, callback=self.imputeKChange, logarithmic=0, ticks=0, maxWidth=200)
60        self.sliderK = OWGUI.qwtHSlider(self.boxImpute, self, "imputeK", box=None, label="K", labelWidth=15, minValue=1, maxValue=999, step=1, precision=0, callback=self.imputeKChange, logarithmic=0, ticks=0, maxWidth=None)
61        self.boxImpute.setDisabled(1)
62        # loess
63        self.boxLoess = QVGroupBox("Smoothing", ca)
64        gl.addWidget(self.boxLoess, 2,0)
65        OWGUI.checkBox(self.boxLoess, self, "smooth", "Loess smoothing", tooltip="Loess profiles, impute missing columns.", callback=self.change)
66        lbl = QLabel("Window size (number of points)", self.boxLoess)
67        lbl.setAlignment(Qt.AlignHCenter)
68        self.sliderW = OWGUI.qwtHSlider(self.boxLoess, self, "windowSize", box=None, label="W", labelWidth=15, minValue=1, maxValue=999, step=1, precision=0, callback=self.smoothWChange, logarithmic=0, ticks=0, maxWidth=None)
69        self.boxLoess.setDisabled(1)
70        # output
71        box = QVGroupBox("Output", ca)
72        gl.addWidget(box, 3,0)
73        OWGUI.checkBox(box, self, 'commitOnChange', 'Commit data on selection change')
74        self.commitBtn = OWGUI.button(box, self, "Commit", callback=self.senddata, disabled=1)
75
76        self.inputs = [("Examples", ExampleTable, self.data), ("Structured Data", DataFiles, self.chipdata)]
77        self.outputs = [("Examples", ExampleTable), ("Structured Data", DataFiles)]
78
79        # data dependent variables
80        self.numRowsMissing = 0
81        self.numRowsMissingChipData = 0
82        self.resize(100,100)
83
84    def change(self):
85        if self.commitOnChange:
86            self.senddata(0)
87
88    def imputeKChange(self):
89        if self.commitOnChange and self.impute:
90            self.senddata(0)
91
92    def smoothWChange(self):
93        if self.commitOnChange and self.smooth:
94            self.senddata(0)
95
96    def setGuiCommonExpChip(self):
97        """Sets GUI features that depend on both inputs, e.g. max. values of sliders, commit button.
98        """
99        # calculate maxK, maxW
100        maxK = 1e9
101        maxW = 1e9
102        if self._dataMA != None:
103            maxK = min(max(self._dataMA.shape[0]/50, 50), self._dataMA.shape[0], maxK)
104            maxW = min(self._dataMA.shape[1], maxW)
105        if self._chipdataMA:
106            maxK = min(max(self._chipdataMA[0][1][0].shape[0]/50., 50), self._chipdataMA[0][1][0].shape[0], maxK)
107            maxW = min(self._chipdataMA[0][1][0].shape[1], maxW)
108        if maxK == 1e9: maxK = 1
109        if maxW == 1e9: maxW = 1
110        # enable sliders and commit button
111        if self._dataMA != None or self._chipdataMA:
112            # set up sliders (only if data present)
113            self.sliderK.setRange(1, maxK, 1)
114            if self.imputeK > maxK:
115                self.sliderK.setValue(maxK)
116                self.imputeK = maxK
117            self.sliderW.setRange(1, maxW, 1)
118            if self.windowSize > maxW:
119                self.sliderW.setValue(maxW)
120                self.windowSize = maxW
121            self.boxImpute.setEnabled(1)
122            self.boxLoess.setEnabled(1)
123            self.commitBtn.setEnabled(1)
124        else:
125            self.boxImpute.setDisabled(1)
126            self.boxLoess.setDisabled(1)
127            self.commitBtn.setDisabled(1)
128
129    def data(self, data):
130        if data != None:
131            self._data = data
132##            self._dataMA = chipstat.orng2ma(data)
133            self._dataMA = data.toNumpyMA("a")[0]
134            # info text
135            self.infoa.setText("Examples: %i profiles on %i points" % (self._dataMA.shape[0], self._dataMA.shape[1]))
136            numTotalMissing = int(Numeric.multiply.reduce(self._dataMA.shape) - MA.count(self._dataMA))
137            if numTotalMissing > 0:
138                numValsByCol = MA.count(self._dataMA, 0)
139                numEmptyCol = Numeric.add.reduce(Numeric.where(numValsByCol==0, 1, 0))
140                colNonEmpty = Numeric.compress(numValsByCol!=0, Numeric.arange(self._dataMA.shape[1]))
141                dataRemEmptyCol = self._dataMA.take(colNonEmpty, 1)
142                self.numRowsMissing = Numeric.add.reduce(Numeric.where(MA.count(dataRemEmptyCol, 1) < dataRemEmptyCol.shape[1], 1, 0))
143                s1 = ""
144                s2 = ""
145                if numEmptyCol > 0: s1 = "s"
146                if self.numRowsMissing > 0: s2 = "s"
147                self.infob.setText("missing %i values, %i column%s completely, %i row%s partially" % (numTotalMissing, numEmptyCol, s1, self.numRowsMissing, s2))
148            else:
149                self.infob.setText("")
150        else:
151            self._data = None
152            self._dataMA = None
153            self.infoa.setText("No examples on input")
154            self.infob.setText("")
155            self.numRowsMissing = 0
156        self.setGuiCommonExpChip()
157        if self.commitOnChange:
158            self.senddata(1)
159
160
161    def chipdata(self, data):
162        """Input data: [(dirname0, [et0, et1, ...]), ...]
163        """
164        self.numRowsMissingChipData = 0
165        self._chipdataMA = []
166        if data != None:
167            self._chipdata = data
168            numValsAll = 0
169            numValsNonMasked = 0
170            numFiles = 0
171            numExamplesList = []
172            attribDict = {}
173            numColMissing = 0
174            for (name, etList) in data:
175                numFiles += len(etList)
176                self._chipdataMA.append((name,[]))
177                for et in etList:
178                    attribDict.update(dict(zip(map(lambda x: x.name, et.domain.attributes), et.domain.attributes)))
179                    numExamplesList.append(len(et))
180                    etm = et.toNumpyMA("a")[0]
181                    colNonMissingInd = Numeric.compress(Numeric.not_equal(MA.count(etm, 0), 0), Numeric.arange(etm.shape[1])) # indices of columns that are not completely missing
182                    numColMissing += etm.shape[1] - colNonMissingInd.shape[0]
183                    self.numRowsMissingChipData += int(Numeric.add.reduce(Numeric.less(MA.count(etm.take(colNonMissingInd, 1), 1), etm.shape[1])))
184                    numValsAll += int(Numeric.multiply.reduce(etm.shape))
185                    numValsNonMasked += int(MA.count(etm))
186                    self._chipdataMA[-1][1].append(etm)
187            # info text
188            self.infoc.setText("Structured Data: %i data files with %i profiles on %i points" % (numFiles, numExamplesList[0], len(attribDict)))
189            numTotalMissing = numValsAll-numValsNonMasked
190            if numTotalMissing > 0:
191                print numTotalMissing, numColMissing, self.numRowsMissingChipData
192                print type(numTotalMissing), type(numColMissing), type(self.numRowsMissingChipData)
193                self.infod.setText("missing %i values, %i column%s completely, %i row%s partially" % (numTotalMissing, numColMissing, ["","s"][numColMissing!=1], self.numRowsMissingChipData, ["","s"][self.numRowsMissingChipData!=1]))
194            else:
195                self.infod.setText("")               
196        else:
197            self._chipdata = None
198            self.infoc.setText("No structured data on input")
199            self.infod.setText("")
200        self.setGuiCommonExpChip()
201        if self.commitOnChange:
202            self.senddata(2)
203
204
205    def senddata(self, outputSelector=0):
206        """outputSelector = [0: examples + chip data | 1: examples | 2: chip data]
207        """
208        assert outputSelector in [0,1,2]
209        # progress bar settings: 1: examples, 2: chip data
210        steps = 0
211        if outputSelector in [0,1]:
212            if self.impute:
213                steps += self.numRowsMissing
214            if self.smooth and self._dataMA != None:
215                steps += self._dataMA.shape[0]
216        if outputSelector in [0,2]:
217            if self.impute:
218                steps += self.numRowsMissingChipData
219            if self.smooth and self._chipdataMA:
220                steps += len(self._chipdataMA[0][1][0]) * reduce(lambda x,y: x+len(y[1]), self._chipdataMA, 0) #self._chipdataMA.shape[2]
221        if steps == 0: steps = 1
222        pbStep = 100./steps
223        self.progressBarInit()
224        if outputSelector in [0,1]:
225            self._sendexampledata(pbStep)
226        if outputSelector in [0,2]:
227            self._sendchipdata(pbStep)
228        self.progressBarFinished()
229
230    def _sendexampledata(self, pbStep):
231        if self._dataMA != None:
232            ma2d = self._dataMA
233            if self.impute:
234                ma2d = chipimpute.kNNimputeMA(ma2d, int(self.imputeK), callback=lambda: self.progressBarAdvance(pbStep))
235            if self.smooth:
236                ws = max(1.1, int(self.windowSize)) # fixes bug in statc.loess
237                ma2d = chipimpute.loessMA(ma2d, ws, 1, callback=lambda: self.progressBarAdvance(pbStep))
238            et = chipstat.ma2orng_keepClassMetas(ma2d, self._data)
239            et.name = self._data.name
240            self.send("Examples", et)
241        else:
242            self.send("Examples", None)
243
244
245    def _sendchipdata(self, pbStep):
246        if self._chipdataMA:
247            chipdataNew = []    # [(dirname0, [et0, et1, ...]), ...]
248            ws = max(1.1, int(self.windowSize)) # fixes bug in statc.loess
249            for sIdx, (name, etmList) in enumerate(self._chipdataMA):
250                chipdataNew.append((name,[]))
251                for eIdx, etm in enumerate(etmList):
252                    if self.impute:
253                        etm = chipimpute.kNNimputeMA(etm, int(self.imputeK), callback=lambda: self.progressBarAdvance(pbStep))
254                    if self.smooth:
255                        etm = chipimpute.loessMA(etm, ws, 1, callback=lambda: self.progressBarAdvance(pbStep))
256##                   chipdataNew[-1][1].append(orange.ExampleTable(et.domain, etm))
257                    etNew = chipstat.ma2orng_keepClassMetas(etm, self._chipdata[sIdx][1][eIdx])
258                    etNew.name = self._chipdata[sIdx][1][eIdx].name
259                    chipdataNew[-1][1].append(etNew)
260            self.send("Structured Data", chipdataNew)
261        else:
262            self.send("Structured Data", None)
263
264
265
266if __name__=="__main__":
267    a=QApplication(sys.argv)
268    ow=OWImputeProfiles()
269    a.setMainWidget(ow)
270    ow.show()
271##    ow.data(orange.ExampleTable("meanExpr_ann_pkaC.tab"))
272##    ow.data(orange.ExampleTable(r"C:\Documents and Settings\peterjuv\My Documents\Orange\ANOVA\DictyChipData_BR_ACS_100_yakApufA\pufA\pufA1.1.xls.tab"))
273##    ow.data(orange.ExampleTable(r"C:\Documents and Settings\peterjuv\My Documents\Orange\ANOVA\potato\I\I_30m_1_1042_teh1.tab"))
274    ow.data(orange.ExampleTable(r"c:\Documents and Settings\peterjuv\My Documents\STEROLTALK\Data Hs\2007-08-29 Banjo\- data\untr maxAbsDiff.tab"))
275    a.exec_loop()
276    ow.saveSettings()
277
278##    from . import OWDataFiles
279##    from Orange.orng import orngSignalManager
280##    signalManager = orngSignalManager.SignalManager(0)
281##    a=QApplication(sys.argv)
282##    ow=OWImputeProfiles(signalManager = signalManager)
283##    a.setMainWidget(ow)
284##    ow.show()
285##    ds = OWDataFiles.OWDataFiles(signalManager = signalManager)
286####    ds.loadData(r"C:\Documents and Settings\peterjuv\My Documents\2005-08 NIB Potato\potato.attrib")
287##    ds.loadData(r"C:\Documents and Settings\peterjuv\My Documents\2005-08 NIB Potato\potato.sub100.avg")
288##    signalManager.addWidget(ow)
289##    signalManager.addWidget(ds)
290##    signalManager.setFreeze(1)
291##    signalManager.addLink(ds, ow, 'Structured Data', 'Structured Data', 1)
292##    signalManager.setFreeze(0)
293##    a.exec_loop()
294##    ow.saveSettings()
Note: See TracBrowser for help on using the repository browser.