Browse Source

Pulled SVN into GIT.

HEAD
Trevor Irons 7 years ago
commit
859e00702c

+ 21
- 0
INSTALL.txt View File

@@ -0,0 +1,21 @@
1
+Akvo is a surface NMR (sNMR) processing utility. Currently preprocessing is supported, but we are adding inversion capabilities. 
2
+
3
+Installation is done in the typical python fashion
4
+
5
+python setup.py build 
6
+python setup.py build_ui   # OPTIONAL, see below
7
+python setup.py install    # requires sudo on most installations 
8
+
9
+# If you are going to be editing the source code, you may prefer to run 
10
+# the develop option which will not require rerunning the install option 
11
+# for each edit. This is entirely optional 
12
+python setup.py develop    # requires sudo on most installations 
13
+
14
+## Building the user interface 
15
+Akvo ships with a
16
+
17
+## On some platforms you may receive an error regarding PyQt5, it should be possible to manually 
18
+## install this via 
19
+pip install PyQt5 
20
+## Or 
21
+pip3 install PyQt5 

+ 17
- 0
LICENSE.txt View File

@@ -0,0 +1,17 @@
1
+Akvo, a surface NMR workbench
2
+Copyright (C) 2014-2017 Trevor P. Irons  
3
+Copyright (C) 2017 M. Andrew Kass  
4
+
5
+This program is free software: you can redistribute it and/or modify
6
+it under the terms of the GNU General Public License as published by
7
+the Free Software Foundation, either version 3 of the License, or
8
+(at your option) any later version.
9
+
10
+This program is distributed in the hope that it will be useful,
11
+but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
+GNU General Public License for more details.
14
+
15
+You should have received a copy of the GNU General Public License
16
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
+

+ 1
- 0
akvo/__init__.py View File

@@ -0,0 +1 @@
1
+#import akvo.tressel.decay

+ 1
- 0
akvo/gui/__init__.py View File

@@ -0,0 +1 @@
1
+#import mainui.py 

BIN
akvo/gui/akvo-crop.png View File


BIN
akvo/gui/akvo.png View File


BIN
akvo/gui/akvo2.png View File


+ 1097
- 0
akvo/gui/akvoGUI.py
File diff suppressed because it is too large
View File


+ 3275
- 0
akvo/gui/main.ui
File diff suppressed because it is too large
View File


+ 9
- 0
akvo/gui/main2ui.py View File

@@ -0,0 +1,9 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+# Form implementation generated from reading ui file 'main.ui'
4
+#
5
+# Created: Fri Jan 11 23:28:48 2013
6
+#      by: PyQt4 UI code generator 4.9.6
7
+#
8
+# WARNING! All changes made in this file will be lost!
9
+

+ 1585
- 0
akvo/gui/mainbu.ui
File diff suppressed because it is too large
View File


+ 1187
- 0
akvo/gui/mainui.py
File diff suppressed because it is too large
View File


+ 586
- 0
akvo/gui/mainui2.py View File

@@ -0,0 +1,586 @@
1
+# -*- coding: utf-8 -*-
2
+
3
+# Form implementation generated from reading ui file 'main.ui'
4
+#
5
+# Created: Fri Jan 11 23:34:58 2013
6
+#      by: PyQt4 UI code generator 4.9.6
7
+#
8
+# WARNING! All changes made in this file will be lost!
9
+
10
+from PyQt4 import QtCore, QtGui
11
+
12
+try:
13
+    _fromUtf8 = QtCore.QString.fromUtf8
14
+except AttributeError:
15
+    def _fromUtf8(s):
16
+        return s
17
+
18
+try:
19
+    _encoding = QtGui.QApplication.UnicodeUTF8
20
+    def _translate(context, text, disambig):
21
+        return QtGui.QApplication.translate(context, text, disambig, _encoding)
22
+except AttributeError:
23
+    def _translate(context, text, disambig):
24
+        return QtGui.QApplication.translate(context, text, disambig)
25
+
26
+class Ui_MainWindow(object):
27
+    def setupUi(self, MainWindow):
28
+        MainWindow.setObjectName(_fromUtf8("MainWindow"))
29
+        MainWindow.resize(1000, 980)
30
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Expanding)
31
+        sizePolicy.setHorizontalStretch(0)
32
+        sizePolicy.setVerticalStretch(0)
33
+        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
34
+        MainWindow.setSizePolicy(sizePolicy)
35
+        MainWindow.setMinimumSize(QtCore.QSize(60, 60))
36
+        MainWindow.setMaximumSize(QtCore.QSize(1000, 16777215))
37
+        MainWindow.setWindowOpacity(1.0)
38
+        MainWindow.setAutoFillBackground(True)
39
+        self.centralwidget = QtGui.QWidget(MainWindow)
40
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
41
+        sizePolicy.setHorizontalStretch(0)
42
+        sizePolicy.setVerticalStretch(0)
43
+        sizePolicy.setHeightForWidth(self.centralwidget.sizePolicy().hasHeightForWidth())
44
+        self.centralwidget.setSizePolicy(sizePolicy)
45
+        self.centralwidget.setMinimumSize(QtCore.QSize(0, 0))
46
+        self.centralwidget.setMaximumSize(QtCore.QSize(1000, 16777215))
47
+        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
48
+        self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
49
+        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
50
+        self.scrollArea = QtGui.QScrollArea(self.centralwidget)
51
+        self.scrollArea.setWidgetResizable(True)
52
+        self.scrollArea.setObjectName(_fromUtf8("scrollArea"))
53
+        self.scrollAreaWidgetContents = QtGui.QWidget()
54
+        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 986, 927))
55
+        self.scrollAreaWidgetContents.setObjectName(_fromUtf8("scrollAreaWidgetContents"))
56
+        self.horizontalLayout_2 = QtGui.QHBoxLayout(self.scrollAreaWidgetContents)
57
+        self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
58
+        self.tabWidget = QtGui.QTabWidget(self.scrollAreaWidgetContents)
59
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
60
+        sizePolicy.setHorizontalStretch(0)
61
+        sizePolicy.setVerticalStretch(0)
62
+        sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth())
63
+        self.tabWidget.setSizePolicy(sizePolicy)
64
+        self.tabWidget.setMinimumSize(QtCore.QSize(940, 0))
65
+        self.tabWidget.setObjectName(_fromUtf8("tabWidget"))
66
+        self.tab = QtGui.QWidget()
67
+        self.tab.setObjectName(_fromUtf8("tab"))
68
+        self.gridLayout = QtGui.QGridLayout(self.tab)
69
+        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
70
+        self.groupBox_4 = QtGui.QGroupBox(self.tab)
71
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
72
+        sizePolicy.setHorizontalStretch(0)
73
+        sizePolicy.setVerticalStretch(0)
74
+        sizePolicy.setHeightForWidth(self.groupBox_4.sizePolicy().hasHeightForWidth())
75
+        self.groupBox_4.setSizePolicy(sizePolicy)
76
+        self.groupBox_4.setMinimumSize(QtCore.QSize(480, 150))
77
+        self.groupBox_4.setFlat(False)
78
+        self.groupBox_4.setCheckable(True)
79
+        self.groupBox_4.setObjectName(_fromUtf8("groupBox_4"))
80
+        self.gridLayout.addWidget(self.groupBox_4, 4, 1, 1, 1)
81
+        self.groupBox = QtGui.QGroupBox(self.tab)
82
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
83
+        sizePolicy.setHorizontalStretch(0)
84
+        sizePolicy.setVerticalStretch(0)
85
+        sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
86
+        self.groupBox.setSizePolicy(sizePolicy)
87
+        self.groupBox.setMinimumSize(QtCore.QSize(460, 230))
88
+        self.groupBox.setAutoFillBackground(False)
89
+        self.groupBox.setFlat(False)
90
+        self.groupBox.setObjectName(_fromUtf8("groupBox"))
91
+        self.headerFileTextBrowser = QtGui.QTextBrowser(self.groupBox)
92
+        self.headerFileTextBrowser.setGeometry(QtCore.QRect(10, 30, 441, 31))
93
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
94
+        sizePolicy.setHorizontalStretch(0)
95
+        sizePolicy.setVerticalStretch(0)
96
+        sizePolicy.setHeightForWidth(self.headerFileTextBrowser.sizePolicy().hasHeightForWidth())
97
+        self.headerFileTextBrowser.setSizePolicy(sizePolicy)
98
+        font = QtGui.QFont()
99
+        font.setPointSize(8)
100
+        font.setItalic(True)
101
+        self.headerFileTextBrowser.setFont(font)
102
+        self.headerFileTextBrowser.setObjectName(_fromUtf8("headerFileTextBrowser"))
103
+        self.label_4 = QtGui.QLabel(self.groupBox)
104
+        self.label_4.setGeometry(QtCore.QRect(10, 70, 81, 21))
105
+        self.label_4.setObjectName(_fromUtf8("label_4"))
106
+        self.pulseTypeTextBrowser = QtGui.QTextBrowser(self.groupBox)
107
+        self.pulseTypeTextBrowser.setGeometry(QtCore.QRect(90, 70, 361, 21))
108
+        font = QtGui.QFont()
109
+        font.setItalic(True)
110
+        self.pulseTypeTextBrowser.setFont(font)
111
+        self.pulseTypeTextBrowser.setAcceptDrops(True)
112
+        self.pulseTypeTextBrowser.setObjectName(_fromUtf8("pulseTypeTextBrowser"))
113
+        self.lcdNumberNuTx = QtGui.QLCDNumber(self.groupBox)
114
+        self.lcdNumberNuTx.setGeometry(QtCore.QRect(160, 100, 64, 23))
115
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
116
+        sizePolicy.setHorizontalStretch(0)
117
+        sizePolicy.setVerticalStretch(0)
118
+        sizePolicy.setHeightForWidth(self.lcdNumberNuTx.sizePolicy().hasHeightForWidth())
119
+        self.lcdNumberNuTx.setSizePolicy(sizePolicy)
120
+        font = QtGui.QFont()
121
+        font.setPointSize(8)
122
+        self.lcdNumberNuTx.setFont(font)
123
+        self.lcdNumberNuTx.setWhatsThis(_fromUtf8(""))
124
+        self.lcdNumberNuTx.setAutoFillBackground(False)
125
+        self.lcdNumberNuTx.setStyleSheet(_fromUtf8("#lcdNumberNuTx {\n"
126
+"color: green;\n"
127
+"background: black;\n"
128
+"}\n"
129
+"\n"
130
+"#lcdNumberNuTx:disabled {\n"
131
+"color: grey;\n"
132
+"background: black;\n"
133
+"}"))
134
+        self.lcdNumberNuTx.setFrameShadow(QtGui.QFrame.Raised)
135
+        self.lcdNumberNuTx.setLineWidth(1)
136
+        self.lcdNumberNuTx.setMidLineWidth(0)
137
+        self.lcdNumberNuTx.setSegmentStyle(QtGui.QLCDNumber.Flat)
138
+        self.lcdNumberNuTx.setProperty("value", 0.0)
139
+        self.lcdNumberNuTx.setObjectName(_fromUtf8("lcdNumberNuTx"))
140
+        self.lcdNumberTuneuF = QtGui.QLCDNumber(self.groupBox)
141
+        self.lcdNumberTuneuF.setGeometry(QtCore.QRect(370, 100, 64, 23))
142
+        self.lcdNumberTuneuF.setStyleSheet(_fromUtf8("#lcdNumberTuneuF {\n"
143
+"color: green;\n"
144
+"background: black;\n"
145
+"}\n"
146
+"\n"
147
+"#lcdNumberTuneuF:disabled {\n"
148
+"color: grey;\n"
149
+"background: black;\n"
150
+"}"))
151
+        self.lcdNumberTuneuF.setLineWidth(1)
152
+        self.lcdNumberTuneuF.setMidLineWidth(0)
153
+        self.lcdNumberTuneuF.setSegmentStyle(QtGui.QLCDNumber.Flat)
154
+        self.lcdNumberTuneuF.setObjectName(_fromUtf8("lcdNumberTuneuF"))
155
+        self.lcdNumberTauPulse1 = QtGui.QLCDNumber(self.groupBox)
156
+        self.lcdNumberTauPulse1.setGeometry(QtCore.QRect(160, 130, 64, 23))
157
+        self.lcdNumberTauPulse1.setStyleSheet(_fromUtf8("#lcdNumberTauPulse1 {\n"
158
+"color: green;\n"
159
+"background: black;\n"
160
+"}\n"
161
+"\n"
162
+"#lcdNumberTauPulse1:disabled {\n"
163
+"color: grey;\n"
164
+"background: black;\n"
165
+"}"))
166
+        self.lcdNumberTauPulse1.setFrameShadow(QtGui.QFrame.Raised)
167
+        self.lcdNumberTauPulse1.setLineWidth(1)
168
+        self.lcdNumberTauPulse1.setMidLineWidth(0)
169
+        self.lcdNumberTauPulse1.setSegmentStyle(QtGui.QLCDNumber.Flat)
170
+        self.lcdNumberTauPulse1.setObjectName(_fromUtf8("lcdNumberTauPulse1"))
171
+        self.label_6 = QtGui.QLabel(self.groupBox)
172
+        self.label_6.setGeometry(QtCore.QRect(10, 100, 91, 21))
173
+        self.label_6.setObjectName(_fromUtf8("label_6"))
174
+        self.label_7 = QtGui.QLabel(self.groupBox)
175
+        self.label_7.setGeometry(QtCore.QRect(10, 130, 141, 21))
176
+        self.label_7.setObjectName(_fromUtf8("label_7"))
177
+        self.label_13 = QtGui.QLabel(self.groupBox)
178
+        self.label_13.setGeometry(QtCore.QRect(260, 160, 91, 21))
179
+        self.label_13.setObjectName(_fromUtf8("label_13"))
180
+        self.lcdNumberTauPulse2 = QtGui.QLCDNumber(self.groupBox)
181
+        self.lcdNumberTauPulse2.setGeometry(QtCore.QRect(160, 160, 64, 23))
182
+        self.lcdNumberTauPulse2.setStyleSheet(_fromUtf8("#lcdNumberTauPulse2 {\n"
183
+"color: green;\n"
184
+"background: black;\n"
185
+"}\n"
186
+"\n"
187
+"#lcdNumberTauPulse2:disabled{\n"
188
+"color: grey;\n"
189
+"background: black;\n"
190
+"}"))
191
+        self.lcdNumberTauPulse2.setLineWidth(1)
192
+        self.lcdNumberTauPulse2.setMidLineWidth(0)
193
+        self.lcdNumberTauPulse2.setSegmentStyle(QtGui.QLCDNumber.Flat)
194
+        self.lcdNumberTauPulse2.setObjectName(_fromUtf8("lcdNumberTauPulse2"))
195
+        self.label_14 = QtGui.QLabel(self.groupBox)
196
+        self.label_14.setGeometry(QtCore.QRect(260, 100, 111, 21))
197
+        self.label_14.setObjectName(_fromUtf8("label_14"))
198
+        self.label_15 = QtGui.QLabel(self.groupBox)
199
+        self.label_15.setGeometry(QtCore.QRect(260, 130, 111, 21))
200
+        self.label_15.setObjectName(_fromUtf8("label_15"))
201
+        self.lcdNumberSampFreq = QtGui.QLCDNumber(self.groupBox)
202
+        self.lcdNumberSampFreq.setEnabled(True)
203
+        self.lcdNumberSampFreq.setGeometry(QtCore.QRect(370, 130, 64, 23))
204
+        self.lcdNumberSampFreq.setStyleSheet(_fromUtf8("#lcdNumberSampFreq {\n"
205
+"color: green;\n"
206
+"background: black;\n"
207
+"}\n"
208
+"\n"
209
+"#lcdNumberSampFreq:disabled{\n"
210
+"color: grey;\n"
211
+"background: black;\n"
212
+"}"))
213
+        self.lcdNumberSampFreq.setLineWidth(1)
214
+        self.lcdNumberSampFreq.setMidLineWidth(0)
215
+        self.lcdNumberSampFreq.setDigitCount(5)
216
+        self.lcdNumberSampFreq.setSegmentStyle(QtGui.QLCDNumber.Flat)
217
+        self.lcdNumberSampFreq.setObjectName(_fromUtf8("lcdNumberSampFreq"))
218
+        self.lcdNumberTauDelay = QtGui.QLCDNumber(self.groupBox)
219
+        self.lcdNumberTauDelay.setEnabled(True)
220
+        self.lcdNumberTauDelay.setGeometry(QtCore.QRect(370, 160, 64, 23))
221
+        self.lcdNumberTauDelay.setStyleSheet(_fromUtf8("#lcdNumberTauDelay {\n"
222
+"color: green;\n"
223
+"background: black;\n"
224
+"}\n"
225
+"\n"
226
+"#lcdNumberTauDelay:disabled {\n"
227
+"color: grey;\n"
228
+"background: black;\n"
229
+"}"))
230
+        self.lcdNumberTauDelay.setLineWidth(1)
231
+        self.lcdNumberTauDelay.setMidLineWidth(0)
232
+        self.lcdNumberTauDelay.setSegmentStyle(QtGui.QLCDNumber.Flat)
233
+        self.lcdNumberTauDelay.setObjectName(_fromUtf8("lcdNumberTauDelay"))
234
+        self.label_16 = QtGui.QLabel(self.groupBox)
235
+        self.label_16.setGeometry(QtCore.QRect(10, 160, 131, 21))
236
+        self.label_16.setObjectName(_fromUtf8("label_16"))
237
+        self.lcdNumberNQ = QtGui.QLCDNumber(self.groupBox)
238
+        self.lcdNumberNQ.setGeometry(QtCore.QRect(160, 190, 64, 23))
239
+        self.lcdNumberNQ.setStyleSheet(_fromUtf8("#lcdNumberNQ {\n"
240
+"color: green;\n"
241
+"background: black;\n"
242
+"}\n"
243
+"\n"
244
+"#lcdNumberNQ:disabled{\n"
245
+"color: grey;\n"
246
+"background: black;\n"
247
+"}"))
248
+        self.lcdNumberNQ.setSegmentStyle(QtGui.QLCDNumber.Flat)
249
+        self.lcdNumberNQ.setObjectName(_fromUtf8("lcdNumberNQ"))
250
+        self.label_9 = QtGui.QLabel(self.groupBox)
251
+        self.label_9.setGeometry(QtCore.QRect(10, 190, 141, 21))
252
+        self.label_9.setObjectName(_fromUtf8("label_9"))
253
+        self.gridLayout.addWidget(self.groupBox, 4, 0, 1, 1)
254
+        self.groupBox_10 = QtGui.QGroupBox(self.tab)
255
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
256
+        sizePolicy.setHorizontalStretch(0)
257
+        sizePolicy.setVerticalStretch(0)
258
+        sizePolicy.setHeightForWidth(self.groupBox_10.sizePolicy().hasHeightForWidth())
259
+        self.groupBox_10.setSizePolicy(sizePolicy)
260
+        self.groupBox_10.setMinimumSize(QtCore.QSize(460, 160))
261
+        self.groupBox_10.setObjectName(_fromUtf8("groupBox_10"))
262
+        self.stacksLineEdit = QtGui.QLineEdit(self.groupBox_10)
263
+        self.stacksLineEdit.setGeometry(QtCore.QRect(110, 30, 91, 21))
264
+        self.stacksLineEdit.setToolTip(_fromUtf8("<html><head/><body><p>Set the stacks that you would like processed.</p><p>This must be a valid set of numpy array indices. Remember that Python uses non end-inclusive indexing. </p><p>So things like [1:24] will include stacks 1-23</p><p>Furthermore [1:8,12:24] will include stacks 1-7 and 12:23. Any list of valid indices will be accepted, but they must be comma seperated. </p></body></html>"))
265
+        self.stacksLineEdit.setObjectName(_fromUtf8("stacksLineEdit"))
266
+        self.label = QtGui.QLabel(self.groupBox_10)
267
+        self.label.setGeometry(QtCore.QRect(10, 30, 51, 20))
268
+        self.label.setToolTip(_fromUtf8(""))
269
+        self.label.setStatusTip(_fromUtf8(""))
270
+        self.label.setObjectName(_fromUtf8("label"))
271
+        self.label_23 = QtGui.QLabel(self.groupBox_10)
272
+        self.label_23.setGeometry(QtCore.QRect(10, 65, 101, 16))
273
+        self.label_23.setObjectName(_fromUtf8("label_23"))
274
+        self.dataChanLineEdit = QtGui.QLineEdit(self.groupBox_10)
275
+        self.dataChanLineEdit.setGeometry(QtCore.QRect(110, 60, 91, 21))
276
+        self.dataChanLineEdit.setObjectName(_fromUtf8("dataChanLineEdit"))
277
+        self.label_24 = QtGui.QLabel(self.groupBox_10)
278
+        self.label_24.setGeometry(QtCore.QRect(220, 36, 101, 16))
279
+        self.label_24.setObjectName(_fromUtf8("label_24"))
280
+        self.DeadTimeSpinBox = QtGui.QDoubleSpinBox(self.groupBox_10)
281
+        self.DeadTimeSpinBox.setGeometry(QtCore.QRect(360, 30, 91, 25))
282
+        self.DeadTimeSpinBox.setMinimum(5.0)
283
+        self.DeadTimeSpinBox.setSingleStep(0.5)
284
+        self.DeadTimeSpinBox.setProperty("value", 5.0)
285
+        self.DeadTimeSpinBox.setObjectName(_fromUtf8("DeadTimeSpinBox"))
286
+        self.label_28 = QtGui.QLabel(self.groupBox_10)
287
+        self.label_28.setGeometry(QtCore.QRect(220, 64, 131, 16))
288
+        self.label_28.setObjectName(_fromUtf8("label_28"))
289
+        self.refChanLineEdit = QtGui.QLineEdit(self.groupBox_10)
290
+        self.refChanLineEdit.setGeometry(QtCore.QRect(360, 60, 91, 21))
291
+        self.refChanLineEdit.setObjectName(_fromUtf8("refChanLineEdit"))
292
+        self.label_30 = QtGui.QLabel(self.groupBox_10)
293
+        self.label_30.setGeometry(QtCore.QRect(12, 96, 91, 16))
294
+        self.label_30.setObjectName(_fromUtf8("label_30"))
295
+        self.CentralVSpinBox = QtGui.QDoubleSpinBox(self.groupBox_10)
296
+        self.CentralVSpinBox.setGeometry(QtCore.QRect(110, 90, 91, 25))
297
+        self.CentralVSpinBox.setMinimum(100.0)
298
+        self.CentralVSpinBox.setMaximum(5000.99)
299
+        self.CentralVSpinBox.setSingleStep(1.0)
300
+        self.CentralVSpinBox.setObjectName(_fromUtf8("CentralVSpinBox"))
301
+        self.label_29 = QtGui.QLabel(self.groupBox_10)
302
+        self.label_29.setGeometry(QtCore.QRect(220, 95, 111, 16))
303
+        self.label_29.setObjectName(_fromUtf8("label_29"))
304
+        self.FIDProcComboBox = QtGui.QComboBox(self.groupBox_10)
305
+        self.FIDProcComboBox.setGeometry(QtCore.QRect(360, 90, 91, 25))
306
+        self.FIDProcComboBox.setObjectName(_fromUtf8("FIDProcComboBox"))
307
+        self.fullWorkflowPushButton = QtGui.QPushButton(self.groupBox_10)
308
+        self.fullWorkflowPushButton.setGeometry(QtCore.QRect(280, 130, 131, 31))
309
+        self.fullWorkflowPushButton.setAutoFillBackground(False)
310
+        self.fullWorkflowPushButton.setStyleSheet(_fromUtf8("#fullWorkflowPushButton {\n"
311
+"background: green;\n"
312
+"}"))
313
+        self.fullWorkflowPushButton.setAutoDefault(False)
314
+        self.fullWorkflowPushButton.setDefault(False)
315
+        self.fullWorkflowPushButton.setFlat(False)
316
+        self.fullWorkflowPushButton.setObjectName(_fromUtf8("fullWorkflowPushButton"))
317
+        self.loadDataPushButton = QtGui.QPushButton(self.groupBox_10)
318
+        self.loadDataPushButton.setGeometry(QtCore.QRect(90, 130, 91, 31))
319
+        self.loadDataPushButton.setObjectName(_fromUtf8("loadDataPushButton"))
320
+        self.gridLayout.addWidget(self.groupBox_10, 5, 0, 1, 1)
321
+        self.groupBox_9 = QtGui.QGroupBox(self.tab)
322
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
323
+        sizePolicy.setHorizontalStretch(0)
324
+        sizePolicy.setVerticalStretch(0)
325
+        sizePolicy.setHeightForWidth(self.groupBox_9.sizePolicy().hasHeightForWidth())
326
+        self.groupBox_9.setSizePolicy(sizePolicy)
327
+        self.groupBox_9.setMinimumSize(QtCore.QSize(480, 100))
328
+        self.groupBox_9.setCheckable(True)
329
+        self.groupBox_9.setObjectName(_fromUtf8("groupBox_9"))
330
+        self.checkBox = QtGui.QCheckBox(self.groupBox_9)
331
+        self.checkBox.setGeometry(QtCore.QRect(30, 30, 171, 20))
332
+        self.checkBox.setObjectName(_fromUtf8("checkBox"))
333
+        self.comboBox_2 = QtGui.QComboBox(self.groupBox_9)
334
+        self.comboBox_2.setGeometry(QtCore.QRect(130, 50, 78, 25))
335
+        self.comboBox_2.setObjectName(_fromUtf8("comboBox_2"))
336
+        self.label_5 = QtGui.QLabel(self.groupBox_9)
337
+        self.label_5.setGeometry(QtCore.QRect(40, 60, 71, 16))
338
+        self.label_5.setObjectName(_fromUtf8("label_5"))
339
+        self.doubleSpinBox = QtGui.QDoubleSpinBox(self.groupBox_9)
340
+        self.doubleSpinBox.setGeometry(QtCore.QRect(390, 20, 62, 25))
341
+        self.doubleSpinBox.setObjectName(_fromUtf8("doubleSpinBox"))
342
+        self.label_8 = QtGui.QLabel(self.groupBox_9)
343
+        self.label_8.setGeometry(QtCore.QRect(220, 20, 161, 20))
344
+        self.label_8.setObjectName(_fromUtf8("label_8"))
345
+        self.gridLayout.addWidget(self.groupBox_9, 5, 1, 1, 1)
346
+        self.groupBox_7 = QtGui.QGroupBox(self.tab)
347
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
348
+        sizePolicy.setHorizontalStretch(0)
349
+        sizePolicy.setVerticalStretch(0)
350
+        sizePolicy.setHeightForWidth(self.groupBox_7.sizePolicy().hasHeightForWidth())
351
+        self.groupBox_7.setSizePolicy(sizePolicy)
352
+        self.groupBox_7.setMinimumSize(QtCore.QSize(480, 100))
353
+        self.groupBox_7.setCheckable(True)
354
+        self.groupBox_7.setObjectName(_fromUtf8("groupBox_7"))
355
+        self.comboBox = QtGui.QComboBox(self.groupBox_7)
356
+        self.comboBox.setGeometry(QtCore.QRect(40, 30, 141, 22))
357
+        self.comboBox.setMouseTracking(True)
358
+        self.comboBox.setToolTip(_fromUtf8(""))
359
+        self.comboBox.setStatusTip(_fromUtf8(""))
360
+        self.comboBox.setWhatsThis(_fromUtf8(""))
361
+        self.comboBox.setObjectName(_fromUtf8("comboBox"))
362
+        self.comboBox.addItem(_fromUtf8(""))
363
+        self.comboBox.addItem(_fromUtf8(""))
364
+        self.gridLayout.addWidget(self.groupBox_7, 2, 1, 1, 1)
365
+        self.label_2 = QtGui.QLabel(self.tab)
366
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
367
+        sizePolicy.setHorizontalStretch(0)
368
+        sizePolicy.setVerticalStretch(0)
369
+        sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
370
+        self.label_2.setSizePolicy(sizePolicy)
371
+        font = QtGui.QFont()
372
+        font.setPointSize(20)
373
+        font.setBold(True)
374
+        font.setWeight(75)
375
+        self.label_2.setFont(font)
376
+        self.label_2.setLayoutDirection(QtCore.Qt.LeftToRight)
377
+        self.label_2.setObjectName(_fromUtf8("label_2"))
378
+        self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1)
379
+        self.groupBox_8 = QtGui.QGroupBox(self.tab)
380
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
381
+        sizePolicy.setHorizontalStretch(0)
382
+        sizePolicy.setVerticalStretch(0)
383
+        sizePolicy.setHeightForWidth(self.groupBox_8.sizePolicy().hasHeightForWidth())
384
+        self.groupBox_8.setSizePolicy(sizePolicy)
385
+        self.groupBox_8.setMinimumSize(QtCore.QSize(480, 150))
386
+        self.groupBox_8.setCheckable(True)
387
+        self.groupBox_8.setObjectName(_fromUtf8("groupBox_8"))
388
+        self.label_3 = QtGui.QLabel(self.groupBox_8)
389
+        self.label_3.setGeometry(QtCore.QRect(30, 60, 111, 16))
390
+        self.label_3.setObjectName(_fromUtf8("label_3"))
391
+        self.spinBox = QtGui.QSpinBox(self.groupBox_8)
392
+        self.spinBox.setGeometry(QtCore.QRect(140, 60, 101, 25))
393
+        self.spinBox.setMaximum(1000)
394
+        self.spinBox.setProperty("value", 300)
395
+        self.spinBox.setObjectName(_fromUtf8("spinBox"))
396
+        self.gridLayout.addWidget(self.groupBox_8, 3, 1, 1, 1)
397
+        self.groupBox_5 = QtGui.QGroupBox(self.tab)
398
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
399
+        sizePolicy.setHorizontalStretch(0)
400
+        sizePolicy.setVerticalStretch(0)
401
+        sizePolicy.setHeightForWidth(self.groupBox_5.sizePolicy().hasHeightForWidth())
402
+        self.groupBox_5.setSizePolicy(sizePolicy)
403
+        self.groupBox_5.setMinimumSize(QtCore.QSize(480, 150))
404
+        self.groupBox_5.setCheckable(True)
405
+        self.groupBox_5.setObjectName(_fromUtf8("groupBox_5"))
406
+        self.gridLayout.addWidget(self.groupBox_5, 1, 1, 1, 1)
407
+        self.mplwidget = MyDynamicMplCanvas(self.tab)
408
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
409
+        sizePolicy.setHorizontalStretch(0)
410
+        sizePolicy.setVerticalStretch(0)
411
+        sizePolicy.setHeightForWidth(self.mplwidget.sizePolicy().hasHeightForWidth())
412
+        self.mplwidget.setSizePolicy(sizePolicy)
413
+        self.mplwidget.setMinimumSize(QtCore.QSize(460, 460))
414
+        self.mplwidget.setObjectName(_fromUtf8("mplwidget"))
415
+        self.gridLayout.addWidget(self.mplwidget, 0, 0, 4, 1)
416
+        self.tabWidget.addTab(self.tab, _fromUtf8(""))
417
+        self.tab_3 = QtGui.QWidget()
418
+        self.tab_3.setObjectName(_fromUtf8("tab_3"))
419
+        self.treeWidget = QtGui.QTreeWidget(self.tab_3)
420
+        self.treeWidget.setGeometry(QtCore.QRect(70, 50, 256, 192))
421
+        self.treeWidget.setObjectName(_fromUtf8("treeWidget"))
422
+        self.treeWidget.headerItem().setText(0, _fromUtf8("1"))
423
+        self.toolBox = QtGui.QToolBox(self.tab_3)
424
+        self.toolBox.setGeometry(QtCore.QRect(320, 460, 79, 137))
425
+        self.toolBox.setObjectName(_fromUtf8("toolBox"))
426
+        self.page = QtGui.QWidget()
427
+        self.page.setGeometry(QtCore.QRect(0, 0, 94, 24))
428
+        self.page.setObjectName(_fromUtf8("page"))
429
+        self.toolBox.addItem(self.page, _fromUtf8(""))
430
+        self.page_2 = QtGui.QWidget()
431
+        self.page_2.setGeometry(QtCore.QRect(0, 0, 94, 24))
432
+        self.page_2.setObjectName(_fromUtf8("page_2"))
433
+        self.toolBox.addItem(self.page_2, _fromUtf8(""))
434
+        self.dateEdit = QtGui.QDateEdit(self.tab_3)
435
+        self.dateEdit.setGeometry(QtCore.QRect(400, 280, 110, 25))
436
+        self.dateEdit.setObjectName(_fromUtf8("dateEdit"))
437
+        self.tabWidget.addTab(self.tab_3, _fromUtf8(""))
438
+        self.tab_2 = QtGui.QWidget()
439
+        self.tab_2.setObjectName(_fromUtf8("tab_2"))
440
+        self.dateEdit_2 = QtGui.QDateEdit(self.tab_2)
441
+        self.dateEdit_2.setGeometry(QtCore.QRect(50, 100, 110, 25))
442
+        self.dateEdit_2.setObjectName(_fromUtf8("dateEdit_2"))
443
+        self.tabWidget.addTab(self.tab_2, _fromUtf8(""))
444
+        self.tab_6 = QtGui.QWidget()
445
+        self.tab_6.setObjectName(_fromUtf8("tab_6"))
446
+        self.tabWidget.addTab(self.tab_6, _fromUtf8(""))
447
+        self.tab_4 = QtGui.QWidget()
448
+        self.tab_4.setObjectName(_fromUtf8("tab_4"))
449
+        self.invertButton = QtGui.QPushButton(self.tab_4)
450
+        self.invertButton.setGeometry(QtCore.QRect(290, 140, 311, 141))
451
+        self.invertButton.setStyleSheet(_fromUtf8("#invertButton {\n"
452
+"font-size:29pt;\n"
453
+"font-weight: bold;\n"
454
+"color: white;\n"
455
+"background: red;\n"
456
+"}"))
457
+        self.invertButton.setObjectName(_fromUtf8("invertButton"))
458
+        self.tabWidget.addTab(self.tab_4, _fromUtf8(""))
459
+        self.tab_5 = QtGui.QWidget()
460
+        self.tab_5.setObjectName(_fromUtf8("tab_5"))
461
+        self.tabWidget.addTab(self.tab_5, _fromUtf8(""))
462
+        self.horizontalLayout_2.addWidget(self.tabWidget)
463
+        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
464
+        self.horizontalLayout.addWidget(self.scrollArea)
465
+        MainWindow.setCentralWidget(self.centralwidget)
466
+        self.menubar = QtGui.QMenuBar(MainWindow)
467
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 20))
468
+        self.menubar.setObjectName(_fromUtf8("menubar"))
469
+        self.menuFile = QtGui.QMenu(self.menubar)
470
+        self.menuFile.setObjectName(_fromUtf8("menuFile"))
471
+        self.menuAbout = QtGui.QMenu(self.menubar)
472
+        self.menuAbout.setObjectName(_fromUtf8("menuAbout"))
473
+        MainWindow.setMenuBar(self.menubar)
474
+        self.statusbar = QtGui.QStatusBar(MainWindow)
475
+        self.statusbar.setObjectName(_fromUtf8("statusbar"))
476
+        MainWindow.setStatusBar(self.statusbar)
477
+        self.actionClose = QtGui.QAction(MainWindow)
478
+        self.actionClose.setObjectName(_fromUtf8("actionClose"))
479
+        self.actionAboutBrewCentral = QtGui.QAction(MainWindow)
480
+        self.actionAboutBrewCentral.setObjectName(_fromUtf8("actionAboutBrewCentral"))
481
+        self.actionNothing = QtGui.QAction(MainWindow)
482
+        self.actionNothing.setObjectName(_fromUtf8("actionNothing"))
483
+        self.actionTemperature = QtGui.QAction(MainWindow)
484
+        self.actionTemperature.setObjectName(_fromUtf8("actionTemperature"))
485
+        self.actionOpen_GMR = QtGui.QAction(MainWindow)
486
+        self.actionOpen_GMR.setCheckable(False)
487
+        self.actionOpen_GMR.setObjectName(_fromUtf8("actionOpen_GMR"))
488
+        self.actionProcess = QtGui.QAction(MainWindow)
489
+        self.actionProcess.setCheckable(True)
490
+        self.actionProcess.setObjectName(_fromUtf8("actionProcess"))
491
+        self.actionOpen_Preprocessed_dataset = QtGui.QAction(MainWindow)
492
+        self.actionOpen_Preprocessed_dataset.setEnabled(False)
493
+        self.actionOpen_Preprocessed_dataset.setObjectName(_fromUtf8("actionOpen_Preprocessed_dataset"))
494
+        self.actionOpen_VC_Preprocessed_dataset = QtGui.QAction(MainWindow)
495
+        self.actionOpen_VC_Preprocessed_dataset.setEnabled(False)
496
+        self.actionOpen_VC_Preprocessed_dataset.setObjectName(_fromUtf8("actionOpen_VC_Preprocessed_dataset"))
497
+        self.actionSave_Preprocesssed_Dataset = QtGui.QAction(MainWindow)
498
+        self.actionSave_Preprocesssed_Dataset.setEnabled(False)
499
+        self.actionSave_Preprocesssed_Dataset.setObjectName(_fromUtf8("actionSave_Preprocesssed_Dataset"))
500
+        self.menuFile.addAction(self.actionOpen_GMR)
501
+        self.menuFile.addSeparator()
502
+        self.menuFile.addAction(self.actionOpen_Preprocessed_dataset)
503
+        self.menuFile.addAction(self.actionOpen_VC_Preprocessed_dataset)
504
+        self.menuFile.addSeparator()
505
+        self.menuFile.addAction(self.actionSave_Preprocesssed_Dataset)
506
+        self.menuFile.addSeparator()
507
+        self.menuFile.addAction(self.actionClose)
508
+        self.menuAbout.addAction(self.actionAboutBrewCentral)
509
+        self.menubar.addAction(self.menuFile.menuAction())
510
+        self.menubar.addAction(self.menuAbout.menuAction())
511
+
512
+        self.retranslateUi(MainWindow)
513
+        self.tabWidget.setCurrentIndex(0)
514
+        self.toolBox.setCurrentIndex(0)
515
+        QtCore.QObject.connect(self.actionClose, QtCore.SIGNAL(_fromUtf8("activated()")), MainWindow.close)
516
+        QtCore.QObject.connect(self.actionAboutBrewCentral, QtCore.SIGNAL(_fromUtf8("activated()")), MainWindow.show)
517
+        QtCore.QMetaObject.connectSlotsByName(MainWindow)
518
+
519
+    def retranslateUi(self, MainWindow):
520
+        MainWindow.setWindowTitle(_translate("MainWindow", "Avko - sNMR Workbench", None))
521
+        self.groupBox_4.setTitle(_translate("MainWindow", "Adaptive Noise Suppresion", None))
522
+        self.groupBox.setTitle(_translate("MainWindow", "Header file info", None))
523
+        self.headerFileTextBrowser.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
524
+"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
525
+"p, li { white-space: pre-wrap; }\n"
526
+"</style></head><body style=\" font-family:\'Sans Serif\'; font-size:8pt; font-weight:400; font-style:italic;\">\n"
527
+"<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><span style=\" font-family:\'DejaVu Serif\'; font-size:9pt;\">Load supported RAW Dataset header from file menu</span></p></body></html>", None))
528
+        self.label_4.setText(_translate("MainWindow", "Pulse Type", None))
529
+        self.pulseTypeTextBrowser.setHtml(_translate("MainWindow", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
530
+"<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n"
531
+"p, li { white-space: pre-wrap; }\n"
532
+"</style></head><body style=\" font-family:\'Sans Serif\'; font-size:9pt; font-weight:400; font-style:italic;\">\n"
533
+"<p style=\"-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:\'DejaVu Serif\'; font-size:10pt;\"><br /></p></body></html>", None))
534
+        self.label_6.setText(_translate("MainWindow", "ฮฝ Tx  [Hz]", None))
535
+        self.label_7.setText(_translate("MainWindow", "ฯ„ Pulse 1 [ms]", None))
536
+        self.label_13.setText(_translate("MainWindow", "ฯ„ Delay [ms]", None))
537
+        self.label_14.setText(_translate("MainWindow", "Tx tuning [ฮผF]", None))
538
+        self.label_15.setText(_translate("MainWindow", "ฮฝ Sampling [Hz]", None))
539
+        self.label_16.setText(_translate("MainWindow", "ฯ„ Pulse 2 [ms]", None))
540
+        self.label_9.setText(_translate("MainWindow", "Num. pulse moments", None))
541
+        self.groupBox_10.setTitle(_translate("MainWindow", "Input parameters", None))
542
+        self.label.setText(_translate("MainWindow", "Stacks", None))
543
+        self.label_23.setText(_translate("MainWindow", "Data Channels", None))
544
+        self.label_24.setText(_translate("MainWindow", "Dead time [ms]", None))
545
+        self.label_28.setText(_translate("MainWindow", "Reference Channels", None))
546
+        self.label_30.setText(_translate("MainWindow", "Central ฮฝ Hz", None))
547
+        self.CentralVSpinBox.setToolTip(_translate("MainWindow", "<html><head/><body><p>In case of off-resonant transmitter pulse, you can set the central frequency that will be used for all processing. This has the biggest impact on the band-pass filter, and the frequencies used in inversion. </p></body></html>", None))
548
+        self.label_29.setText(_translate("MainWindow", "Process FID #", None))
549
+        self.FIDProcComboBox.setToolTip(_translate("MainWindow", "<html><head/><body><p>For T1 or CPMG pulses, which pulse(s) would you like to process. Note that for very short delay T1 pulses, the first pulse may be disabled. </p></body></html>", None))
550
+        self.fullWorkflowPushButton.setText(_translate("MainWindow", "Full Workflow", None))
551
+        self.loadDataPushButton.setText(_translate("MainWindow", "Load Data", None))
552
+        self.groupBox_9.setTitle(_translate("MainWindow", "SmartStack^TM", None))
553
+        self.checkBox.setText(_translate("MainWindow", "Correct phase jitter", None))
554
+        self.label_5.setText(_translate("MainWindow", "Outlier test", None))
555
+        self.label_8.setText(_translate("MainWindow", "Instrument phase delay", None))
556
+        self.groupBox_7.setTitle(_translate("MainWindow", "Band-Pass Filter", None))
557
+        self.comboBox.setAccessibleDescription(_translate("MainWindow", "Hello", None))
558
+        self.comboBox.setItemText(0, _translate("MainWindow", "Butterworth", None))
559
+        self.comboBox.setItemText(1, _translate("MainWindow", "Chebychev Type II", None))
560
+        self.label_2.setText(_translate("MainWindow", "         Preprocessing Workflow", None))
561
+        self.groupBox_8.setTitle(_translate("MainWindow", "Downsample and truncate", None))
562
+        self.label_3.setText(_translate("MainWindow", "Truncate [ms]", None))
563
+        self.groupBox_5.setTitle(_translate("MainWindow", "Despike Filter", None))
564
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Preprocess RAW", None))
565
+        self.toolBox.setItemText(self.toolBox.indexOf(self.page), _translate("MainWindow", "Page 1", None))
566
+        self.toolBox.setItemText(self.toolBox.indexOf(self.page_2), _translate("MainWindow", "Page 2", None))
567
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Data QC", None))
568
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Model Parameters", None))
569
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_6), _translate("MainWindow", "Forward modelling", None))
570
+        self.invertButton.setText(_translate("MainWindow", "Invert", None))
571
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("MainWindow", "Inversion", None))
572
+        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_5), _translate("MainWindow", "Analysis", None))
573
+        self.menuFile.setTitle(_translate("MainWindow", "&File", None))
574
+        self.menuAbout.setTitle(_translate("MainWindow", "About", None))
575
+        self.actionClose.setText(_translate("MainWindow", "&Close", None))
576
+        self.actionAboutBrewCentral.setText(_translate("MainWindow", "Brew Central", None))
577
+        self.actionNothing.setText(_translate("MainWindow", "Nothing", None))
578
+        self.actionTemperature.setText(_translate("MainWindow", "Temperature", None))
579
+        self.actionOpen_GMR.setText(_translate("MainWindow", "Open GMR RAW header", None))
580
+        self.actionOpen_GMR.setIconText(_translate("MainWindow", "Open GMR RAW dataset(s)", None))
581
+        self.actionProcess.setText(_translate("MainWindow", "Process", None))
582
+        self.actionOpen_Preprocessed_dataset.setText(_translate("MainWindow", "Open Avko Preprocessed dataset", None))
583
+        self.actionOpen_VC_Preprocessed_dataset.setText(_translate("MainWindow", "Open VC Preprocessed dataset", None))
584
+        self.actionSave_Preprocesssed_Dataset.setText(_translate("MainWindow", "Save Preprocesssed Dataset", None))
585
+
586
+from mydynamicmplcanvas import MyDynamicMplCanvas

+ 299
- 0
akvo/gui/mydynamicmplcanvas.py View File

@@ -0,0 +1,299 @@
1
+from __future__ import unicode_literals
2
+import sys
3
+import os
4
+import random
5
+import matplotlib
6
+# Make sure that we are using QT5
7
+matplotlib.use('Qt5Agg')
8
+from PyQt5 import QtCore, QtWidgets
9
+
10
+from numpy import arange, sin, pi
11
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
12
+from matplotlib.figure import Figure
13
+import numpy as np
14
+
15
+class MyMplCanvas(FigureCanvas):
16
+    
17
+    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
18
+    def __init__(self, parent=None, width=3, height=4, dpi=100):
19
+        
20
+        self.fig = Figure(figsize=(width, height), dpi=dpi)
21
+        FigureCanvas.__init__(self, self.fig)
22
+
23
+        self.setParent(parent)
24
+        FigureCanvas.updateGeometry(self)
25
+
26
+    def compute_initial_figure(self):
27
+        pass
28
+
29
+    def clicked(self):
30
+        print ("Clicked")
31
+
32
+class MyDynamicMplCanvas(MyMplCanvas):
33
+
34
+    """A canvas that updates itself every second with a new plot."""
35
+    def __init__(self, *args, **kwargs):
36
+        
37
+        MyMplCanvas.__init__(self, *args, **kwargs)
38
+        self.ax1 = self.fig.add_axes([.125,.1,.725,.8])
39
+        self.ax2 = self.ax1.twinx() # fig.add_axes([.125,.1,.725,.8])
40
+        self.compute_initial_figure()
41
+
42
+    def reAxH(self, num, shx=True, shy=True):
43
+        try:
44
+            self.fig.clear()
45
+        except:
46
+            pass
47
+        for n in range(num):
48
+            if n == 0:
49
+                self.ax1 = self.fig.add_subplot( 1, num, 1 )
50
+                self.ax1.tick_params(axis='both', which='major', labelsize=8)
51
+                self.ax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
52
+                self.ax1.yaxis.get_offset_text().set_size(8) 
53
+            if n == 1:
54
+                self.ax2 = self.fig.add_subplot( 1, num, 2 )
55
+                self.ax2.tick_params(axis='both', which='major', labelsize=8)
56
+                self.ax2.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
57
+                self.ax2.yaxis.get_offset_text().set_size(8) 
58
+            if n == 2:
59
+                self.ax3 = self.fig.add_subplot( 1, num, 3 )
60
+                self.ax3.tick_params(axis='both', which='major', labelsize=8)
61
+                self.ax3.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
62
+                self.ax3.yaxis.get_offset_text().set_size(8) 
63
+            if n == 3:
64
+                self.ax4 = self.fig.add_subplot( 1, num, 4 )
65
+                self.ax4.tick_params(axis='both', which='major', labelsize=8)
66
+                self.ax4.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
67
+                self.ax4.yaxis.get_offset_text().set_size(8) 
68
+    
69
+    def reAxH2(self, num, shx=True, shy=True):
70
+        try:
71
+            for ax in fig.axes:
72
+                self.fig.delaxes(ax)
73
+        except:
74
+            pass
75
+
76
+        try:
77
+            self.fig.clear()
78
+        except:
79
+            pass
80
+        
81
+        for n in range(num):
82
+            if n == 0:
83
+                self.ax1 = self.fig.add_subplot( 2, num, 1 )
84
+                self.ax1.tick_params(axis='both', which='major', labelsize=8)
85
+                self.ax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
86
+                self.ax1.yaxis.get_offset_text().set_size(8) 
87
+                self.ax21 = self.fig.add_subplot( 2, num, num+1 )
88
+                self.ax21.tick_params(axis='both', which='major', labelsize=8)
89
+                self.ax21.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
90
+                self.ax21.yaxis.get_offset_text().set_size(8) 
91
+            if n == 1:
92
+                self.ax2 = self.fig.add_subplot( 2, num, 2, sharex=self.ax1, sharey=self.ax1 )
93
+                self.ax2.tick_params(axis='both', which='major', labelsize=8)
94
+                self.ax2.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
95
+                self.ax2.yaxis.get_offset_text().set_size(8) 
96
+                self.ax22 = self.fig.add_subplot( 2, num, num+2, sharex=self.ax21, sharey=self.ax21 )
97
+                self.ax22.tick_params(axis='both', which='major', labelsize=8)
98
+                self.ax22.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
99
+                self.ax22.yaxis.get_offset_text().set_size(8) 
100
+            if n == 2:
101
+                self.ax3 = self.fig.add_subplot( 2, num, 3, sharex=self.ax1, sharey=self.ax1 )
102
+                self.ax3.tick_params(axis='both', which='major', labelsize=8)
103
+                self.ax3.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
104
+                self.ax3.yaxis.get_offset_text().set_size(8) 
105
+                self.ax23 = self.fig.add_subplot( 2, num, num+3, sharex=self.ax21, sharey=self.ax21 )
106
+                self.ax23.tick_params(axis='both', which='major', labelsize=8)
107
+                self.ax23.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
108
+                self.ax23.yaxis.get_offset_text().set_size(8) 
109
+            if n == 3:
110
+                self.ax4 = self.fig.add_subplot( 2, num, 4, sharex=self.ax1, sharey=self.ax1 )
111
+                self.ax4.tick_params(axis='both', which='major', labelsize=8)
112
+                self.ax4.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
113
+                self.ax4.yaxis.get_offset_text().set_size(8) 
114
+                self.ax24 = self.fig.add_subplot( 2, num, num+4, sharex=self.ax21, sharey=self.ax21 )
115
+                self.ax24.tick_params(axis='both', which='major', labelsize=8)
116
+                self.ax24.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
117
+                self.ax24.yaxis.get_offset_text().set_size(8) 
118
+            if n == 4:
119
+                self.ax5 = self.fig.add_subplot( 2, num, 5, sharex=self.ax1, sharey=self.ax1 )
120
+                self.ax5.tick_params(axis='both', which='major', labelsize=8)
121
+                self.ax5.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
122
+                self.ax5.yaxis.get_offset_text().set_size(8) 
123
+                self.ax25 = self.fig.add_subplot( 2, num, num+5, sharex=self.ax21, sharey=self.ax21 )
124
+                self.ax25.tick_params(axis='both', which='major', labelsize=8)
125
+                self.ax25.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
126
+                self.ax25.yaxis.get_offset_text().set_size(8) 
127
+            if n == 5:
128
+                self.ax6 = self.fig.add_subplot( 2, num, 6, sharex=self.ax1, sharey=self.ax1 )
129
+                self.ax6.tick_params(axis='both', which='major', labelsize=8)
130
+                self.ax6.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
131
+                self.ax6.yaxis.get_offset_text().set_size(8) 
132
+                self.ax26 = self.fig.add_subplot( 2, num, num+6, sharex=self.ax21, sharey=self.ax21 )
133
+                self.ax26.tick_params(axis='both', which='major', labelsize=8)
134
+                self.ax26.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
135
+                self.ax26.yaxis.get_offset_text().set_size(8) 
136
+            if n == 6:
137
+                self.ax7 = self.fig.add_subplot( 2, num, 7, sharex=self.ax1, sharey=self.ax1 )
138
+                self.ax7.tick_params(axis='both', which='major', labelsize=8)
139
+                self.ax7.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
140
+                self.ax7.yaxis.get_offset_text().set_size(8) 
141
+                self.ax27 = self.fig.add_subplot( 2, num, num+7, sharex=self.ax21, sharey=self.ax21 )
142
+                self.ax27.tick_params(axis='both', which='major', labelsize=8)
143
+                self.ax27.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
144
+                self.ax27.yaxis.get_offset_text().set_size(8) 
145
+            if n == 7:
146
+                self.ax8 = self.fig.add_subplot( 2, num, 8, sharex=self.ax1, sharey=self.ax1 )
147
+                self.ax8.tick_params(axis='both', which='major', labelsize=8)
148
+                self.ax8.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
149
+                self.ax8.yaxis.get_offset_text().set_size(8) 
150
+                self.ax28 = self.fig.add_subplot( 2, num, num+8, sharex=self.ax21, sharey=self.ax21 )
151
+                self.ax28.tick_params(axis='both', which='major', labelsize=8)
152
+                self.ax28.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
153
+                self.ax28.yaxis.get_offset_text().set_size(8) 
154
+
155
+    def reAx2(self, shx=True, shy=True):
156
+
157
+        try:
158
+            self.fig.clear()
159
+        except:
160
+            pass
161
+
162
+        try:
163
+            self.ax1.clear() 
164
+            self.delaxes(self.ax1) #.clear()
165
+        except:
166
+            pass
167
+        
168
+        try:    
169
+            self.delaxes(self.ax3) #.clear()
170
+        except:
171
+            pass
172
+        
173
+        try:
174
+            self.ax2.clear() 
175
+            self.delaxes(self.ax2) #.clear()
176
+        except:
177
+            pass
178
+
179
+        self.ax1 = self.fig.add_subplot(211)
180
+        if shx and shy:
181
+            self.ax2 = self.fig.add_subplot(212, sharex=self.ax1, sharey=self.ax1)
182
+        elif shx == True:
183
+            self.ax2 = self.fig.add_subplot(212, sharex=self.ax1) 
184
+        elif shy == True:
185
+            self.ax2 = self.fig.add_subplot(212, sharey=self.ax1) 
186
+        else:
187
+            self.ax2 = self.fig.add_subplot(212)
188
+
189
+        self.ax1.tick_params(axis='both', which='major', labelsize=8)
190
+        self.ax2.tick_params(axis='both', which='major', labelsize=8)
191
+
192
+        self.ax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
193
+        self.ax2.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
194
+
195
+        self.ax1.yaxis.get_offset_text().set_size(8) 
196
+        self.ax2.yaxis.get_offset_text().set_size(8) 
197
+
198
+    def reAx3(self, shx=True, shy=True):
199
+
200
+        try:
201
+            self.fig.clear()
202
+        except:
203
+            pass
204
+
205
+        try:
206
+            self.ax1.clear() 
207
+            self.delaxes(self.ax1) #.clear()
208
+        except:
209
+            pass
210
+            
211
+        try:
212
+            self.ax2.clear() 
213
+            self.delaxes(self.ax2) #.clear()
214
+        except:
215
+            pass
216
+        
217
+        try:    
218
+            self.ax3.clear() 
219
+            self.delaxes(self.ax3) #.clear()
220
+        except:
221
+            pass
222
+
223
+        self.ax1 = self.fig.add_subplot(211)
224
+        if shx and shy:
225
+            self.ax2 = self.fig.add_subplot(212, sharex=self.ax1, sharey=self.ax1)
226
+        elif shx:
227
+            self.ax2 = self.fig.add_subplot(212, sharex=self.ax1) 
228
+        elif shy:
229
+            self.ax2 = self.fig.add_subplot(212, sharey=self.ax1) 
230
+        else:
231
+            self.ax2 = self.fig.add_subplot(212) 
232
+
233
+        self.ax3 = self.ax1.twinx()
234
+
235
+        self.ax1.tick_params(axis='both', which='major', labelsize=8)
236
+        self.ax2.tick_params(axis='both', which='major', labelsize=8)
237
+        self.ax3.tick_params(axis='both', which='major', labelsize=8)
238
+
239
+        self.ax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
240
+        self.ax2.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
241
+        self.ax3.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
242
+
243
+        self.ax1.yaxis.get_offset_text().set_size(8) 
244
+        self.ax2.yaxis.get_offset_text().set_size(8)    
245
+        self.ax3.yaxis.get_offset_text().set_size(8)    
246
+ 
247
+    def reAx4(self):
248
+
249
+        try:
250
+            self.fig.clear()
251
+        except:
252
+            pass
253
+
254
+        # two main axes
255
+        self.ax1 = self.fig.add_axes([0.15, 0.55,   0.625, 0.3672])
256
+        self.ax2 = self.fig.add_axes([0.15, 0.135,  0.625, 0.3672])
257
+        
258
+        # for colourbars
259
+        self.cax1 = self.fig.add_axes([0.8, 0.55,   0.025, 0.3672])
260
+        self.cax2 = self.fig.add_axes([0.8, 0.135,  0.025, 0.3672])
261
+        
262
+        self.ax1.tick_params(axis='both', which='major', labelsize=8)
263
+        self.ax2.tick_params(axis='both', which='major', labelsize=8)
264
+
265
+        self.ax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
266
+        self.ax2.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
267
+
268
+        self.ax1.yaxis.get_offset_text().set_size(8) 
269
+        self.ax2.yaxis.get_offset_text().set_size(8) 
270
+
271
+        self.cax1.tick_params(axis='both', which='major', labelsize=8)
272
+        self.cax2.tick_params(axis='both', which='major', labelsize=8)
273
+
274
+        self.cax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
275
+        self.cax2.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
276
+
277
+        self.cax1.yaxis.get_offset_text().set_size(8) #.get_text()
278
+        self.cax2.yaxis.get_offset_text().set_size(8) #.get_text()
279
+
280
+        self.cax1.tick_params(labelsize=8) 
281
+        self.cax2.tick_params(labelsize=8)
282
+
283
+
284
+    def compute_initial_figure(self):
285
+        
286
+        t = np.arange(0,.3,1e-4)
287
+        x = np.cos(t*2000.*np.pi*2)*np.exp(-t/.07)
288
+        x2 = np.exp(-t/.07)
289
+        dp = self.ax1.plot(t, x, 'r',label='test function')
290
+        dp2 = self.ax2.plot(t, x2, 'r',label='test function2')
291
+        self.ax1.set_xlabel("Time [s]", fontsize=8)
292
+        self.ax1.set_ylabel("Signal [nV]", fontsize=8)
293
+
294
+        self.ax1.tick_params(axis='both', which='major', labelsize=8)
295
+        self.ax1.tick_params(axis='both', which='minor', labelsize=6)
296
+
297
+        self.ax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y') 
298
+        self.ax1.legend(prop={'size':6})
299
+

+ 35
- 0
akvo/gui/mydynamicmplcanvasnavigator.py View File

@@ -0,0 +1,35 @@
1
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
2
+from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
3
+from matplotlib.figure import Figure
4
+import numpy as np
5
+
6
+import sys
7
+from PyQt5 import QtCore, QtGui
8
+
9
+#from mydynamicmplcanvas import MyMplCanvas
10
+
11
+class MyMplCanvasN(FigureCanvas):
12
+    
13
+    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
14
+    def __init__(self, parent=None, width=3, height=.2, dpi=100):
15
+        
16
+        self.fig = Figure(figsize=(width, height), dpi=dpi)
17
+        FigureCanvas.__init__(self, self.fig)
18
+
19
+        self.setParent(parent)
20
+        FigureCanvas.updateGeometry(self)
21
+
22
+    def compute_initial_figure(self):
23
+        pass
24
+
25
+    def clicked(self):
26
+        print ("Clicked")
27
+
28
+class MyDynamicMplCanvasNavigator(MyMplCanvasN):
29
+    
30
+    def __init__(self, *args, **kwargs):
31
+        
32
+        MyMplCanvasN.__init__(self, *args, **kwargs)
33
+
34
+    def setCanvas(self, canvas):
35
+        NavigationToolbar(canvas, self)

+ 13
- 0
akvo/gui/quad.r View File

@@ -0,0 +1,13 @@
1
+
2
+# Define 
3
+Xc <- function(E0, df, tt, phi, T2) {
4
+	E0 * -sin(2*pi*df*tt + phi) * exp(-tt/T2)
5
+}
6
+
7
+Yc <- function(E0, df, tt, phi, T2) {
8
+	E0 * cos(2*pi*df*tt + phi) * exp(-tt/T2)
9
+}
10
+
11
+#QI <- function(E0, df, tt, phi, T2, X, Y) {
12
+#	(X-Xc(E0, df, tt, phi, T2))  + (Y-Yc(E0, df, tt, phi, T2))
13
+#}

+ 3
- 0
akvo/gui/replace.sh View File

@@ -0,0 +1,3 @@
1
+#!/bin/bash
2
+python2-pyuic4 main.ui > mainui.py
3
+sed 's/QtGui.KLed/KLed/g' mainui.py > mainui2.py

+ 1490
- 0
akvo/gui/scroll.ui
File diff suppressed because it is too large
View File


+ 219
- 0
akvo/gui/temp.py View File

@@ -0,0 +1,219 @@
1
+"""
2
+This demo demonstrates how to embed a matplotlib (mpl) plot 
3
+into a PyQt4 GUI application, including:
4
+
5
+* Using the navigation toolbar
6
+* Adding data to the plot
7
+* Dynamically modifying the plot's properties
8
+* Processing mpl events
9
+* Saving the plot to a file from a menu
10
+
11
+The main goal is to serve as a basis for developing rich PyQt GUI
12
+applications featuring mpl plots (using the mpl OO API).
13
+
14
+Eli Bendersky (eliben@gmail.com)
15
+License: this code is in the public domain
16
+Last modified: 19.01.2009
17
+"""
18
+import sys, os, random
19
+from PyQt4.QtCore import *
20
+from PyQt4.QtGui import *
21
+
22
+import matplotlib
23
+from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
24
+from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
25
+from matplotlib.figure import Figure
26
+
27
+
28
+class AppForm(QMainWindow):
29
+    def __init__(self, parent=None):
30
+        QMainWindow.__init__(self, parent)
31
+        self.setWindowTitle('Demo: PyQt with matplotlib')
32
+
33
+        self.create_menu()
34
+        self.create_main_frame()
35
+        self.create_status_bar()
36
+
37
+        self.textbox.setText('1 2 3 4')
38
+        self.on_draw()
39
+
40
+    def save_plot(self):
41
+        file_choices = "PNG (*.png)|*.png"
42
+        
43
+        path = unicode(QFileDialog.getSaveFileName(self, 
44
+                        'Save file', '', 
45
+                        file_choices))
46
+        if path:
47
+            self.canvas.print_figure(path, dpi=self.dpi)
48
+            self.statusBar().showMessage('Saved to %s' % path, 2000)
49
+    
50
+    def on_about(self):
51
+        msg = """ A demo of using PyQt with matplotlib:
52
+        
53
+         * Use the matplotlib navigation bar
54
+         * Add values to the text box and press Enter (or click "Draw")
55
+         * Show or hide the grid
56
+         * Drag the slider to modify the width of the bars
57
+         * Save the plot to a file using the File menu
58
+         * Click on a bar to receive an informative message
59
+        """
60
+        QMessageBox.about(self, "About the demo", msg.strip())
61
+    
62
+    def on_pick(self, event):
63
+        # The event received here is of the type
64
+        # matplotlib.backend_bases.PickEvent
65
+        #
66
+        # It carries lots of information, of which we're using
67
+        # only a small amount here.
68
+        # 
69
+        box_points = event.artist.get_bbox().get_points()
70
+        msg = "You've clicked on a bar with coords:\n %s" % box_points
71
+        
72
+        QMessageBox.information(self, "Click!", msg)
73
+    
74
+    def on_draw(self):
75
+        """ Redraws the figure
76
+        """
77
+        str = unicode(self.textbox.text())
78
+        self.data = map(int, str.split())
79
+        
80
+        x = range(len(self.data))
81
+
82
+        # clear the axes and redraw the plot anew
83
+        #
84
+        self.axes.clear()        
85
+        self.axes.grid(self.grid_cb.isChecked())
86
+        
87
+        self.axes.bar(
88
+            left=x, 
89
+            height=self.data, 
90
+            width=self.slider.value() / 100.0, 
91
+            align='center', 
92
+            alpha=0.44,
93
+            picker=5)
94
+        
95
+        self.canvas.draw()
96
+    
97
+    def create_main_frame(self):
98
+        self.main_frame = QWidget()
99
+        
100
+        # Create the mpl Figure and FigCanvas objects. 
101
+        # 5x4 inches, 100 dots-per-inch
102
+        #
103
+        self.dpi = 100
104
+        self.fig = Figure((5.0, 4.0), dpi=self.dpi)
105
+        self.canvas = FigureCanvas(self.fig)
106
+        self.canvas.setParent(self.main_frame)
107
+        
108
+        # Since we have only one plot, we can use add_axes 
109
+        # instead of add_subplot, but then the subplot
110
+        # configuration tool in the navigation toolbar wouldn't
111
+        # work.
112
+        #
113
+        self.axes = self.fig.add_subplot(111)
114
+        
115
+        # Bind the 'pick' event for clicking on one of the bars
116
+        #
117
+        self.canvas.mpl_connect('pick_event', self.on_pick)
118
+        
119
+        # Create the navigation toolbar, tied to the canvas
120
+        #
121
+        self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame)
122
+        
123
+        # Other GUI controls
124
+        # 
125
+        self.textbox = QLineEdit()
126
+        self.textbox.setMinimumWidth(200)
127
+        self.connect(self.textbox, SIGNAL('editingFinished ()'), self.on_draw)
128
+        
129
+        self.draw_button = QPushButton("&Draw")
130
+        self.connect(self.draw_button, SIGNAL('clicked()'), self.on_draw)
131
+        
132
+        self.grid_cb = QCheckBox("Show &Grid")
133
+        self.grid_cb.setChecked(False)
134
+        self.connect(self.grid_cb, SIGNAL('stateChanged(int)'), self.on_draw)
135
+        
136
+        slider_label = QLabel('Bar width (%):')
137
+        self.slider = QSlider(Qt.Horizontal)
138
+        self.slider.setRange(1, 100)
139
+        self.slider.setValue(20)
140
+        self.slider.setTracking(True)
141
+        self.slider.setTickPosition(QSlider.TicksBothSides)
142
+        self.connect(self.slider, SIGNAL('valueChanged(int)'), self.on_draw)
143
+        
144
+        #
145
+        # Layout with box sizers
146
+        # 
147
+        hbox = QHBoxLayout()
148
+        
149
+        for w in [  self.textbox, self.draw_button, self.grid_cb,
150
+                    slider_label, self.slider]:
151
+            hbox.addWidget(w)
152
+            hbox.setAlignment(w, Qt.AlignVCenter)
153
+        
154
+        vbox = QVBoxLayout()
155
+        vbox.addWidget(self.canvas)
156
+        vbox.addWidget(self.mpl_toolbar)
157
+        vbox.addLayout(hbox)
158
+        
159
+        self.main_frame.setLayout(vbox)
160
+        self.setCentralWidget(self.main_frame)
161
+    
162
+    def create_status_bar(self):
163
+        self.status_text = QLabel("This is a demo")
164
+        self.statusBar().addWidget(self.status_text, 1)
165
+        
166
+    def create_menu(self):        
167
+        self.file_menu = self.menuBar().addMenu("&File")
168
+        
169
+        load_file_action = self.create_action("&Save plot",
170
+            shortcut="Ctrl+S", slot=self.save_plot, 
171
+            tip="Save the plot")
172
+        quit_action = self.create_action("&Quit", slot=self.close, 
173
+            shortcut="Ctrl+Q", tip="Close the application")
174
+        
175
+        self.add_actions(self.file_menu, 
176
+            (load_file_action, None, quit_action))
177
+        
178
+        self.help_menu = self.menuBar().addMenu("&Help")
179
+        about_action = self.create_action("&About", 
180
+            shortcut='F1', slot=self.on_about, 
181
+            tip='About the demo')
182
+        
183
+        self.add_actions(self.help_menu, (about_action,))
184
+
185
+    def add_actions(self, target, actions):
186
+        for action in actions:
187
+            if action is None:
188
+                target.addSeparator()
189
+            else:
190
+                target.addAction(action)
191
+
192
+    def create_action(  self, text, slot=None, shortcut=None, 
193
+                        icon=None, tip=None, checkable=False, 
194
+                        signal="triggered()"):
195
+        action = QAction(text, self)
196
+        if icon is not None:
197
+            action.setIcon(QIcon(":/%s.png" % icon))
198
+        if shortcut is not None:
199
+            action.setShortcut(shortcut)
200
+        if tip is not None:
201
+            action.setToolTip(tip)
202
+            action.setStatusTip(tip)
203
+        if slot is not None:
204
+            self.connect(action, SIGNAL(signal), slot)
205
+        if checkable:
206
+            action.setCheckable(True)
207
+        return action
208
+
209
+
210
+def main():
211
+    app = QApplication(sys.argv)
212
+    form = AppForm()
213
+    form.show()
214
+    app.exec_()
215
+
216
+
217
+if __name__ == "__main__":
218
+    main()
219
+

BIN
akvo/gui/turtle.png View File


+ 35
- 0
akvo/terminal/SEGPlot.py View File

@@ -0,0 +1,35 @@
1
+#################################################################################
2
+# GJI final pub specs                                                           #
3
+import matplotlib                                                               #
4
+from matplotlib import rc                                                       #
5
+#matplotlib.rcParams['text.latex.preamble']=[r"\usepackage{amsmath,amssymb}"]    #
6
+matplotlib.rcParams['text.latex.preamble']=[r"\usepackage{timet,amsmath,amssymb}"]  #
7
+rc('font',**{'family':'serif','serif':['timet']})                                   #
8
+rc('font',**{'size':8})                                                             #
9
+rc('text', usetex=True)                                                             #
10
+# converts pc that GJI is defined in to inches                                      # 
11
+# In GEOPHYSICS \textwidth = 42pc                                               #
12
+#        \columnwidth = 20pc                                                    #
13
+#        one column widthe figures are 20 picas                                 #
14
+#        one and one third column figures are 26 picas                          #
15
+def pc2in(pc):                                                                  #
16
+    return pc*12/72.27                                                          #
17
+#################################################################################
18
+import numpy as np
19
+light_grey = np.array([float(248)/float(255)]*3)
20
+
21
+def fixLeg(legend):
22
+    rect = legend.get_frame()
23
+    #rect.set_color('None')
24
+    rect.set_facecolor(light_grey)
25
+    rect.set_linewidth(0.0)
26
+    rect.set_alpha(0.5)
27
+
28
+def deSpine(ax1):
29
+    spines_to_remove = ['top', 'right']
30
+    for spine in spines_to_remove:
31
+        ax1.spines[spine].set_visible(False)
32
+    #ax1.xaxis.set_ticks_position('none')
33
+    #ax1.yaxis.set_ticks_position('none')
34
+    ax1.get_xaxis().tick_bottom()
35
+    ax1.get_yaxis().tick_left()

+ 51
- 0
akvo/terminal/USGSPlots.py View File

@@ -0,0 +1,51 @@
1
+import sys
2
+import numpy as np
3
+import matplotlib.pyplot as plt
4
+import plotyaml
5
+
6
+__author__ = "M. Andy Kass"
7
+__version__ = "$Revision 0.1"
8
+__date__ = "$Date: 2017-05-25"
9
+
10
+
11
+class USGSPlots:
12
+
13
+    def getData(self,fname,chan):
14
+            
15
+        self.channels = []
16
+        for part in chan.split(','):
17
+            if ':' in part:
18
+                a,b = part.split(':')
19
+                a,b = int(a), int(b)
20
+                self.channels.extend(range(a,b))
21
+            else:
22
+                a = int(part)
23
+                self.channels.append(a)
24
+        #print self.channels
25
+
26
+        self.data = []
27
+        for c in self.channels:
28
+            nm = "Chan. " + str(c)
29
+            self.data.append(plotyaml.loadAkvoData(fname,nm))
30
+
31
+
32
+        return 0
33
+
34
+    def plotSingleDecay(self,pm,chan=1):
35
+       
36
+
37
+        return 42
38
+
39
+
40
+    def plotAllDecays(self,chan=1):
41
+
42
+        return 42
43
+
44
+    def plotAverageFID(self,chan=1):
45
+
46
+        return 42
47
+
48
+    def plotSpectrum(self,chan=1):
49
+
50
+        return 42
51
+ 

+ 192
- 0
akvo/terminal/epsPlots.py View File

@@ -0,0 +1,192 @@
1
+from SEGPlot import *
2
+
3
+import sys
4
+sys.path.append( '../tressel' )
5
+
6
+import matplotlib.pyplot as plt
7
+import matplotlib.ticker
8
+import scipy.io as sio
9
+import scipy.signal as signal
10
+import numpy as np
11
+
12
+import mrsurvey
13
+import pickle
14
+import decay
15
+import cmaps
16
+plt.register_cmap(name='viridis', cmap=cmaps.viridis)
17
+plt.register_cmap(name='inferno', cmap=cmaps.inferno)
18
+plt.register_cmap(name='inferno_r', cmap=cmaps.inferno_r)
19
+
20
+plt.register_cmap(name='magma', cmap=cmaps.magma)
21
+plt.register_cmap(name='magma_r', cmap=cmaps.magma_r)
22
+
23
+
24
+class canvas():
25
+    
26
+    def __init__(self):
27
+        self.fig = plt.figure( figsize=(pc2in(20),pc2in(20) ) )
28
+        self.ax1 = self.fig.add_subplot((211))
29
+        self.ax2 = self.fig.add_subplot((212), sharex=self.ax1)
30
+   
31
+    def draw(self):
32
+        plt.draw() 
33
+
34
+    def reAx2(self):
35
+        try:
36
+            self.fig.clear()
37
+        except:
38
+            pass
39
+
40
+        try:
41
+            self.ax1.clear() 
42
+            self.delaxes(self.ax1) #.clear()
43
+        except:
44
+            pass
45
+            
46
+        try:
47
+            self.ax2.clear() 
48
+            self.delaxes(self.ax2) #.clear()
49
+        except:
50
+            pass
51
+
52
+        self.ax1 = self.fig.add_subplot(211)
53
+        self.ax2 = self.fig.add_subplot(212)
54
+
55
+        self.ax1.tick_params(axis='both', which='major', labelsize=8)
56
+        self.ax2.tick_params(axis='both', which='major', labelsize=8)
57
+
58
+        self.ax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
59
+        self.ax2.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
60
+
61
+        self.ax1.yaxis.get_offset_text().set_size(8) 
62
+        self.ax2.yaxis.get_offset_text().set_size(8) 
63
+
64
+    def reAx4(self):
65
+        try:
66
+            self.fig.clear()
67
+        except:
68
+            pass
69
+
70
+        # two main axes
71
+        self.ax1 = self.fig.add_axes([0.15, 0.55,   0.625, 0.3672])
72
+        self.ax2 = self.fig.add_axes([0.15, 0.135 , 0.625, 0.3672])
73
+        
74
+        # for colourbars
75
+        self.cax1 = self.fig.add_axes([0.8, 0.55 ,  0.025, 0.3672])
76
+        self.cax2 = self.fig.add_axes([0.8, 0.135,  0.025, 0.3672])
77
+        
78
+        self.ax1.tick_params(axis='both', which='major', labelsize=8)
79
+        self.ax2.tick_params(axis='both', which='major', labelsize=8)
80
+
81
+        self.ax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
82
+        self.ax2.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
83
+
84
+        self.ax1.yaxis.get_offset_text().set_size(8) 
85
+        self.ax2.yaxis.get_offset_text().set_size(8) 
86
+
87
+        self.cax1.tick_params(axis='both', which='major', labelsize=8)
88
+        self.cax2.tick_params(axis='both', which='major', labelsize=8)
89
+
90
+        self.cax1.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
91
+        self.cax2.ticklabel_format(style='sci', scilimits=(0,0), axis='y')  
92
+
93
+        self.cax1.yaxis.get_offset_text().set_size(8) #.get_text()
94
+        self.cax2.yaxis.get_offset_text().set_size(8) #.get_text()
95
+
96
+        self.cax1.tick_params(labelsize=8) 
97
+        self.cax2.tick_params(labelsize=8)
98
+        
99
+        #self.ax1.yaxis.minorticks_off()
100
+        #self.ax2.yaxis.minorticks_off()
101
+        
102
+        plt.tick_params(
103
+            axis='y',          # changes apply to the x-axis
104
+            which='minor',      # both major and minor ticks are affected
105
+            bottom='off',      # ticks along the bottom edge are off
106
+            top='off',         # ticks along the top edge are off
107
+            labelbottom='off') 
108
+
109
+if __name__ == "__main__":
110
+   
111
+    first = True
112
+    for ffile in sys.argv[1::]: 
113
+        Canvas = canvas()
114
+        pfile = file(ffile)
115
+        unpickle = pickle.Unpickler(pfile)
116
+        MRS = mrsurvey.GMRDataProcessor()
117
+        MRS.DATADICT = unpickle.load()
118
+        MRS.pulseType = MRS.DATADICT["INFO"]["pulseType"]
119
+        MRS.transFreq = MRS.DATADICT["INFO"]["transFreq"]
120
+        MRS.pulseLength = MRS.DATADICT["INFO"]["pulseLength"]
121
+        MRS.TuneCapacitance = MRS.DATADICT["INFO"]["TuneCapacitance"]
122
+        MRS.samp = MRS.DATADICT["INFO"]["samp"]
123
+        MRS.nPulseMoments = MRS.DATADICT["INFO"]["nPulseMoments"]
124
+        MRS.deadTime = MRS.DATADICT["INFO"]["deadTime"]
125
+
126
+        MRS.quadDet(1, True, Canvas)
127
+        MRS.gateIntegrate(14, 1, Canvas )
128
+
129
+        #Canvas.fig.suptitle(r"\textbf{Experiment 0, channel 4}",  fontsize=8) #, fontweight='bold')
130
+        Canvas.ax1.set_title(r"Experiment 0, channel 4",  fontsize=8) 
131
+        #Canvas.ax1.set_title("Channel 4")
132
+
133
+
134
+
135
+        plt.savefig("test.eps", dpi=2200)
136
+
137
+        if first:
138
+            mat = MRS.DATADICT["CA"]
139
+            pmat = MRS.DATADICT["CP"]
140
+            first = False
141
+        else:
142
+            mat += MRS.DATADICT["CA"]
143
+            pmat += MRS.DATADICT["CP"]
144
+
145
+    quadSum = True
146
+    if quadSum:
147
+    
148
+        Canvas.ax1.clear() 
149
+        Canvas.ax2.clear() 
150
+        Canvas.cax1.clear() 
151
+        Canvas.cax2.clear() 
152
+        pulse = "Pulse 1"
153
+        clip = 1
154
+        QQ = np.average(MRS.DATADICT[pulse]["Q"], axis=1 )
155
+        im1 = Canvas.ax1.pcolormesh( 1e3*MRS.DATADICT[pulse]["TIMES"][clip-1:-clip], QQ, mat,  cmap='coolwarm_r', rasterized=True, vmin=-np.max(np.abs(mat)), vmax=np.max(np.abs(mat)))
156
+        im2 = Canvas.ax2.pcolormesh( 1e3*MRS.DATADICT[pulse]["TIMES"][clip-1:-clip], QQ, pmat, cmap='coolwarm_r', rasterized=True, vmin=-np.max(np.abs(pmat)), vmax=np.max(np.abs(pmat)))
157
+
158
+        cb2 = Canvas.fig.colorbar(im2, cax=Canvas.cax2)
159
+        cb2.set_label("Noise residual (nV)", fontsize=8)
160
+
161
+
162
+        #canvas.ax2.yaxis.set_ticks( QQ[0,9::7] )       
163
+        
164
+        Canvas.ax1.set_yscale('log')
165
+        Canvas.ax2.set_yscale('log')
166
+        
167
+        qlabs = np.append(np.concatenate( (QQ[0:1],QQ[9::10] )), QQ[-1] ) 
168
+        Canvas.ax1.yaxis.set_ticks( qlabs ) # np.append(np.concatenate( (QQ[0:1],QQ[9::10] )), QQ[-1] ) )
169
+        Canvas.ax2.yaxis.set_ticks( qlabs ) #np.append(np.concatenate( (QQ[0:1],QQ[9::10] )), QQ[-1] ) )
170
+        #formatter = matplotlib.ticker.LogFormatter(10, labelOnlyBase=False)
171
+        formatter = matplotlib.ticker.FuncFormatter(lambda x, pos: str((round(x,1)))) 
172
+        Canvas.ax1.yaxis.set_major_formatter(formatter)#matplotlib.ticker.FormatStrFormatter('%d.1'))
173
+        Canvas.ax2.yaxis.set_major_formatter(formatter)#matplotlib.ticker.FormatStrFormatter('%d.1')) 
174
+
175
+        plt.setp(Canvas.ax1.get_xticklabels(), visible=False)
176
+ 
177
+        t = 1e3*MRS.DATADICT[pulse]["TIMES"][clip-1:-clip],
178
+        Canvas.ax1.set_ylim( np.min(QQ), np.max(QQ) )
179
+        Canvas.ax2.set_ylim( np.min(QQ), np.max(QQ) )
180
+        Canvas.ax1.set_xlim( np.min(t), np.max(t) )
181
+        Canvas.ax2.set_xlim( np.min(t), np.max(t) )
182
+
183
+        cb1 = Canvas.fig.colorbar(im1, cax=Canvas.cax1)
184
+        cb1.set_label("Phased amplitude (nV)", fontsize=8)
185
+
186
+        Canvas.ax2.set_xlabel(r"Time (ms)", fontsize=8)
187
+        Canvas.ax1.set_ylabel(r"$q$ ( $\mathrm{A}\cdot\mathrm{s}$)", fontsize=8)
188
+        Canvas.ax2.set_ylabel(r"$q$ ( $\mathrm{A}\cdot\mathrm{s}$)", fontsize=8)
189
+
190
+        plt.savefig("quadSum.eps")
191
+
192
+    plt.show()

+ 64
- 0
akvo/terminal/plotyaml.py View File

@@ -0,0 +1,64 @@
1
+import yaml
2
+import os, sys
3
+import numpy as np
4
+
5
+def slicedict(d, s):
6
+    return {k:v for k,v in d.items() if k.startswith(s)}
7
+
8
+# Converts Lemma/Merlin/Akvo serialized Eigen arrays into numpy ones for use by Python 
9
+class VectorXr(yaml.YAMLObject):
10
+    """
11
+    Converts Lemma/Merlin/Akvo serialized Eigen arrays into numpy ones for use by Python 
12
+    """
13
+    yaml_tag = u'VectorXr'
14
+    def __init__(self, array):
15
+        self.size = np.shape(array)[0]
16
+        self.data = array.tolist()
17
+    def __repr__(self):
18
+        # Converts to numpy array on import 
19
+        return "np.array(%r)" % (self.data)
20
+
21
+class AkvoData(yaml.YAMLObject):
22
+    """
23
+    Reads an Akvo serialized dataset into a standard python dictionary 
24
+    """
25
+    yaml_tag = u'AkvoData'
26
+    def __init__(self, array):
27
+        pass
28
+        #self.size = np.shape(array)[0]
29
+        #self.Imp = array.tolist()
30
+    def __repr__(self):
31
+        # Converts to a dictionary with Eigen vectors represented as Numpy arrays 
32
+        return self
33
+
34
+def loadAkvoData(fnamein, chan):
35
+    """ Loads data from an Akvo YAML file. The 0.02 is hard coded as the pulse length. This needs to be 
36
+        corrected in future kernel calculations. The current was reported but not the pulse length. 
37
+    """
38
+    fname = (os.path.splitext(fnamein)[0])
39
+    with open(fnamein, 'r') as stream:
40
+        try:
41
+            AKVO = (yaml.load(stream))
42
+        except yaml.YAMLError as exc:
43
+            print(exc)
44
+    return AKVO 
45
+
46
+def plotQt( akvo ):
47
+    import matplotlib.pyplot as plt
48
+    plt.style.use('ggplot')
49
+    for pulse in akvo.Gated:
50
+        if pulse[0:5] == "Pulse":
51
+            #print(akvo.GATED[pulse].keys())
52
+            nq = akvo.Pulses[pulse]["current"].size
53
+            for chan in slicedict(akvo.Gated[pulse], "Chan."):
54
+                # accumulate pulse moments
55
+                X = np.zeros( (nq, len( akvo.Gated[pulse]["abscissa"].data )) )
56
+                for q in range(nq):
57
+                    plt.plot(  akvo.Gated[pulse]["abscissa"].data,  akvo.Gated[pulse][chan]["Q-" + str(q)+" CA"].data ) 
58
+                    X[q] = akvo.Gated[pulse][chan]["Q-" + str(q)+" CA"].data
59
+    plt.matshow(X)
60
+
61
+    plt.show()
62
+if __name__ == "__main__":
63
+    akvo = loadAkvoData( sys.argv[1] , "Chan. 1")
64
+    plotQt(akvo)

+ 24
- 0
akvo/terminal/tempPlots.py View File

@@ -0,0 +1,24 @@
1
+from USGSPlots import USGSPlots
2
+import plotyaml
3
+import sys
4
+
5
+
6
+if len(sys.argv) != 4 and len(sys.argv) != 2:
7
+    print('Usage:')
8
+    print('whatever.py filename channel option')
9
+    print('Use whatever.py -h for detailed help')
10
+    sys.exit()
11
+
12
+if len(sys.argv) == 2:
13
+    print('help!')
14
+    sys.exit()
15
+
16
+
17
+fname = str(sys.argv[1])
18
+chan = sys.argv[2]
19
+
20
+myplot = USGSPlots()
21
+
22
+myplot.getData(fname,chan)
23
+
24
+

+ 3
- 0
akvo/tressel/__init__.py View File

@@ -0,0 +1,3 @@
1
+#import decay
2
+#import rotate
3
+#import mrsurvey 

+ 545
- 0
akvo/tressel/adapt.py View File

@@ -0,0 +1,545 @@
1
+import numpy as np
2
+from numpy.linalg import lstsq
3
+from numpy.linalg import norm
4
+from numpy import fft 
5
+
6
+import pylab
7
+
8
+from scipy.signal import correlate
9
+
10
+def autocorr(x):
11
+    #result = np.correlate(x, x, mode='full')
12
+    result = correlate(x, x, mode='full')
13
+    return result[result.size/2:]
14
+
15
+class AdaptiveFilter:
16
+
17
+    def __init__(self, mu):
18
+        self.mu = mu
19
+
20
+    def adapt_filt_Ref(self, x, R, M, mu, PCA, lambda2=0.95, H0=0):
21
+        """ Taken from .m file
22
+        This function is written to allow the user to filter a input signal   
23
+        with an adaptive filter that utilizes 2 reference signals instead of  
24
+        the standard method which allows for only 1 reference signal.         
25
+        Author: Rob Clemens              Date: 3/16/06                       
26
+        Modified and ported to Python, now takes arbitray number of reference points  
27
+        """
28
+        #from akvo.tressel import pca 
29
+        import akvo.tressel.pca as pca 
30
+
31
+        if np.shape(x) != np.shape(R[0]): # or np.shape(x) != np.shape(rx1):
32
+            print ("Error, non aligned")
33
+            exit(1)
34
+        
35
+        if PCA == "Yes":
36
+            # PCA decomposition on ref channels so signals are less related
37
+            R, K, means = pca.pca( R )
38
+        
39
+        if all(H0) == 0:
40
+            H = np.zeros( (len(R)*M))
41
+            #print ("resetting filter")
42
+        else:
43
+            H = H0
44
+        Rn = np.ones(len(R)*M) / mu 
45
+        
46
+        r_ = np.zeros( (len(R), M) ) 
47
+        e = np.zeros(len(x)) # error, desired output
48
+        ilambda = lambda2**-1
49
+
50
+        for z in range(0, len(x)):
51
+            # Only look forwards, to avoid distorting the lates times 
52
+            # (run backwards, if opposite and you don't care about distorting very late time.)
53
+            for ir in range(len(R)):
54
+                if z < M:
55
+                    r_[ir,0:z] = R[ir][0:z]
56
+                    r_[ir,z:M] = 0 
57
+                else:
58
+                    # TODO, use np.delete and np.append to speed this up
59
+                    r_[ir,:] = R[ir][z-M:z]
60
+            # reshape            
61
+            r_n = np.reshape(r_, -1) #concatenate((r_v, r_h ))
62
+
63
+            #K      = np.dot( np.diag(Rn,0), r_n) / (lambda2 + np.dot(r_n*Rn, r_n))  # Create/update K
64
+            K      = (Rn* r_n) / (lambda2 + np.dot(r_n*Rn, r_n))  # Create/update K
65
+            e[z]   = x[z] - np.dot(r_n.T, H)             # e is the filtered signal, input - r(n) * Filter Coefs
66
+            H     += K*e[z];                             # Update Filter Coefficients
67
+            Rn     = ilambda*Rn - ilambda*np.dot(np.dot(K, r_n.T), Rn)     # Update R(n)
68
+        return e, H
69
+
70
+    def transferFunctionFFT(self, D, R, reg=1e-2):
71
+        from akvo.tressel import pca
72
+        """
73
+            Computes the transfer function (H) between a Data channel and 
74
+            a number of Reference channels. The Matrices D and R are 
75
+            expected to be in the frequency domain on input.
76
+            | R1'R1 R1'R2 R1'R3|   |h1|   |R1'D|
77
+            | R2'R1 R2'R2 R2'R3| * |h2| = |R2'D|
78
+            | R3'R1 R3'R2 R3'R3|   |h3|   |R3'D|
79
+
80
+            Returns the corrected array 
81
+        """
82
+
83
+        # PCA decomposition on ref channels so signals are less related
84
+        #transMatrix, K, means = pca.pca( np.array([rx0, rx1]))   
85
+        #RR = np.zeros(( np.shape(R[0])[0]*np.shape(R[0])[1], len(R)))
86
+#         RR = np.zeros(( len(R), np.shape(R[0])[0]*np.shape(R[0])[1] ))
87
+#         for ir in range(len(R)):
88
+#             RR[ir,:] = np.reshape(R[ir], -1)
89
+#         transMatrix, K, means = pca.pca(RR)    
90
+#         #R rx0 = transMatrix[0,:]
91
+#         # rx1 = transMatrix[1,:]
92
+#         for ir in range(len(R)):
93
+#             R[ir] = transMatrix[ir,0]
94
+
95
+        import scipy.linalg 
96
+        import akvo.tressel.pca as pca 
97
+        # Compute as many transfer functions as len(R)
98
+        # A*H = B
99
+        nref = len(R)
100
+        H = np.zeros( (np.shape(D)[1], len(R)), dtype=complex )
101
+        for iw in range(np.shape(D)[1]):
102
+            A = np.zeros( (nref, nref), dtype=complex )
103
+            B = np.zeros( (nref) , dtype=complex)
104
+            for ii in range(nref):
105
+                for jj in range(nref):
106
+                    # build A
107
+                    A[ii,jj] = np.dot(R[ii][:,iw], R[jj][:,iw])                 
108
+
109
+                # build B
110
+                B[ii] = np.dot( R[ii][:,iw], D[:,iw] )
111
+
112
+            # compute H(iw)
113
+            #linalg.solve(a,b) if a is square
114
+            #print "A", A
115
+            #print "B", B
116
+            # TODO, regularise this solve step? So as to not fit the spurious noise
117
+            #print np.shape(B), np.shape(A) 
118
+            #H[iw, :] = scipy.linalg.solve(A,B)
119
+            H[iw, :] = scipy.linalg.lstsq(A,B,cond=reg)[0]
120
+            #print "lstqt", np.shape(scipy.linalg.lstsq(A,B))
121
+            #print "solve", scipy.linalg.solve(A,B)
122
+            #H[iw,:]  = scipy.linalg.lstsq(A,B) # otherwise 
123
+                #H = np.zeros( (np.shape(D)[1], )   )
124
+        #print H #A, B
125
+        Error = np.zeros(np.shape(D), dtype=complex)
126
+        for ir in range(nref):
127
+            for q in range( np.shape(D)[0] ):
128
+                #print "dimcheck", np.shape(H[:,ir]), np.shape(R[ir][q,:] )
129
+                Error[q,:] += H[:,ir]*R[ir][q,:]
130
+        return D - Error
131
+
132
+    def adapt_filt_tworefFreq(self, x, rx0, rx1, M, lambda2=0.95):
133
+        """ Frequency domain version of above
134
+        """
135
+        from akvo.tressel import pca 
136
+
137
+        pylab.figure()
138
+        pylab.plot(rx0)
139
+        pylab.plot(rx1)
140
+
141
+        # PCA decomposition on ref channels so signals are less related
142
+        transMatrix, K, means = pca.pca( np.array([rx0, rx1]))    
143
+        rx0 = transMatrix[:,0]
144
+        rx1 = transMatrix[:,1]
145
+        
146
+        pylab.plot(rx0)
147
+        pylab.plot(rx1)
148
+        pylab.show()
149
+        exit()
150
+
151
+        if np.shape(x) != np.shape(rx0) or np.shape(x) != np.shape(rx1):
152
+            print ("Error, non aligned")
153
+            exit(1)
154
+
155
+        wx = fft.rfft(x)
156
+        wr0 = fft.rfft(rx0)
157
+        wr1 = fft.rfft(rx1)
158
+ 
159
+        H = np.zeros( (2*M), dtype=complex ) 
160
+        ident_mat = np.eye((2*M))
161
+        Rn = ident_mat / 0.1
162
+        r_v = np.zeros( (M), dtype=complex ) 
163
+        r_h = np.zeros( (M), dtype=complex ) 
164
+        e = np.zeros(len(x), dtype=complex )
165
+        ilambda = lambda2**-1
166
+
167
+        for z in range(0, len(wx)):
168
+            # TODO Padd with Zeros or truncate if M >,< arrays 
169
+            r_v = wr0[::-1][:M] 
170
+            r_h = wr1[::-1][:M] 
171
+            r_n = np.concatenate((r_v, r_h ))
172
+            K      = np.dot(Rn, r_n) / (lambda2 + np.dot(np.dot(r_n.T, Rn), r_n))  # Create/update K
173
+            e[z]   = wx[z] - np.dot(r_n,H)        # e is the filtered signal, input - r(n) * Filter Coefs
174
+            H     += K * e[z];                    # Update Filter Coefficients
175
+            Rn     = ilambda*Rn - ilambda*K*r_n.T*Rn  # Update R(n)
176
+        
177
+        return fft.irfft(e)
178
+
179
+    def iter_filt_refFreq(self, x, rx0, Ahat=.05, Bhat=.5, k=0.05):
180
+
181
+        X = np.fft.rfft(x)
182
+        X0 = np.copy(X)
183
+        RX0 = np.fft.rfft(rx0)
184
+
185
+        # step 0
186
+        Abs2HW = []
187
+        alphai =  k * (np.abs(Ahat)**2 / np.abs(Bhat)**2) 
188
+        betai  =  k * (1. / (np.abs(Bhat)**2) ) 
189
+        Hw     =  ((1.+alphai) * np.abs(X)**2 ) / (np.abs(X)**2 + betai*(np.abs(RX0)**2))
190
+        H      =  np.abs(Hw)**2
191
+        pylab.ion()
192
+        pylab.figure()
193
+        for i in range(10):
194
+            #print "alphai", alphai
195
+            #print "betai", betai
196
+            #print "Hw", Hw
197
+            alphai = k * (np.abs(Ahat)**2 / np.abs(Bhat)**2) * np.product(H, axis=0)
198
+            betai  = k * (1. / np.abs(Bhat)**2) * np.product(H, axis=0)
199
+            # update signal
200
+            Hw   =  ((1.+alphai) * np.abs(X)**2) / (np.abs(X)**2 + betai*np.abs(RX0)**2)
201
+            Hw = np.nan_to_num(Hw)
202
+            X *= Hw
203
+            H = np.vstack( (H, np.abs(Hw)**2) )
204
+            #print "Hw", Hw
205
+            pylab.cla()
206
+            pylab.plot(Hw)
207
+            #pylab.plot(np.abs(X))
208
+            #pylab.plot(np.abs(RX0))
209
+            pylab.draw()
210
+            raw_input("wait")
211
+
212
+        pylab.cla()
213
+        pylab.ioff()
214
+        #return np.fft.irfft(X0-X)
215
+        return np.fft.irfft(X)
216
+
217
+    def iter_filt_refFreq(self, x, rx0, rx1, Ahat=.1, Bhat=1., k=0.001):
218
+
219
+        X = np.fft.rfft(x)
220
+        X0 = np.copy(X)
221
+        RX0 = np.fft.rfft(rx0)
222
+        RX1 = np.fft.rfft(rx1)
223
+
224
+        # step 0
225
+        alphai =  k * (np.abs(Ahat)**2 / np.abs(Bhat)**2) 
226
+        betai  =  k * (1. / (np.abs(Bhat)**2) ) 
227
+        #Hw     =  ((1.+alphai) * np.abs(X)**2 ) / (np.abs(X)**2 + betai*(np.abs(RX0)**2))
228
+        H      =  np.ones(len(X)) # abs(Hw)**2
229
+        #pylab.ion()
230
+        #pylab.figure(334)
231
+        for i in range(1000):
232
+            #print "alphai", alphai
233
+            #print "betai", betai
234
+            #print "Hw", Hw
235
+            alphai = k * (np.abs(Ahat)**2 / np.abs(Bhat)**2) * np.product(H, axis=0)
236
+            betai  = k * (1. / np.abs(Bhat)**2) * np.product(H, axis=0)
237
+            # update signal
238
+            Hw   =  ((1.+alphai) * np.abs(X)**2) / (np.abs(X)**2 + betai*np.abs(RX0)**2)
239
+            Hw = np.nan_to_num(Hw)
240
+            X *= Hw #.conjugate
241
+            #H = np.vstack((H, np.abs(Hw)**2) )
242
+            H = np.vstack((H, np.abs(Hw)) )
243
+            #print "Hw", Hw
244
+            #pylab.cla()
245
+            #pylab.plot(Hw)
246
+            #pylab.plot(np.abs(X))
247
+            #pylab.plot(np.abs(RX0))
248
+            #pylab.draw()
249
+            #raw_input("wait")
250
+
251
+        #pylab.cla()
252
+        #pylab.ioff()
253
+        return np.fft.irfft(X0-X)
254
+        #return np.fft.irfft(X)
255
+
256
+    def Tdomain_DFT(self, desired, input, S):
257
+        """ Lifted from Adaptive filtering toolbox. Modefied to accept more than one input 
258
+            vector
259
+        """
260
+        
261
+        # Initialisation Procedure
262
+        nCoefficients =   S["filterOrderNo"]/2+1
263
+        nIterations   =   len(desired)
264
+
265
+        # Pre Allocations
266
+        errorVector  = np.zeros(nIterations, dtype='complex')
267
+        outputVector = np.zeros(nIterations, dtype='complex')
268
+        
269
+        # Initial State
270
+        coefficientVectorDFT =   np.fft.rfft(S["initialCoefficients"])/np.sqrt(float(nCoefficients))
271
+        desiredDFT           =   np.fft.rfft(desired)
272
+        powerVector          =   S["initialPower"]*np.ones(nCoefficients)
273
+
274
+        # Improve source code regularity, pad with zeros
275
+        # TODO, confirm zeros(nCoeffics) not nCoeffics-1
276
+        prefixedInput  =   np.concatenate([np.zeros(nCoefficients-1), np.array(input)])
277
+
278
+        # Body
279
+        pylab.ion()
280
+        pylab.figure(11)
281
+        for it in range(nIterations): # = 1:nIterations,
282
+            
283
+            regressorDFT = np.fft.rfft(prefixedInput[it:it+nCoefficients][::-1]) /\
284
+                           np.sqrt(float(nCoefficients))
285
+
286
+            # Summing two column vectors
287
+            powerVector = S["alpha"] * (regressorDFT*np.conjugate(regressorDFT)) + \
288
+                                  (1.-S["alpha"])*(powerVector)
289
+
290
+            pylab.cla()
291
+            #pylab.plot(prefixedInput[::-1], 'b')
292
+            #pylab.plot(prefixedInput[it:it+nCoefficients][::-1], 'g', linewidth=3)
293
+            #pylab.plot(regressorDFT.real)
294
+            #pylab.plot(regressorDFT.imag)
295
+            pylab.plot(powerVector.real)
296
+            pylab.plot(powerVector.imag)
297
+            #pylab.plot(outputVector)
298
+            #pylab.plot(errorVector.real)
299
+            #pylab.plot(errorVector.imag)
300
+            pylab.draw()
301
+            #raw_input("wait")
302
+
303
+            outputVector[it] = np.dot(coefficientVectorDFT.T, regressorDFT)
304
+
305
+            #errorVector[it] = desired[it] - outputVector[it]
306
+            errorVector[it] = desiredDFT[it] - outputVector[it]
307
+
308
+            #print errorVector[it], desired[it], outputVector[it]
309
+
310
+            # Vectorized
311
+            coefficientVectorDFT += (S["step"]*np.conjugate(errorVector[it])*regressorDFT) /\
312
+                                    (S['gamma']+powerVector)
313
+
314
+        return np.real(np.fft.irfft(errorVector))
315
+        #coefficientVector = ifft(coefficientVectorDFT)*sqrt(nCoefficients);
316
+
317
+    def Tdomain_DCT(self, desired, input, S):
318
+        """ Lifted from Adaptive filtering toolbox. Modefied to accept more than one input 
319
+            vector. Uses cosine transform
320
+        """
321
+        from scipy.fftpack import dct
322
+ 
323
+        # Initialisation Procedure
324
+        nCoefficients =   S["filterOrderNo"]+1
325
+        nIterations   =   len(desired)
326
+
327
+        # Pre Allocations
328
+        errorVector  = np.zeros(nIterations)
329
+        outputVector = np.zeros(nIterations)
330
+        
331
+        # Initial State
332
+        coefficientVectorDCT =   dct(S["initialCoefficients"]) #/np.sqrt(float(nCoefficients))
333
+        desiredDCT           =   dct(desired)
334
+        powerVector          =   S["initialPower"]*np.ones(nCoefficients)
335
+
336
+        # Improve source code regularity, pad with zeros
337
+        prefixedInput  =   np.concatenate([np.zeros(nCoefficients-1), np.array(input)])
338
+        
339
+        # Body
340
+        #pylab.figure(11)
341
+        #pylab.ion()
342
+        for it in range(0, nIterations): # = 1:nIterations,
343
+            
344
+            regressorDCT = dct(prefixedInput[it:it+nCoefficients][::-1], type=2) 
345
+            #regressorDCT = dct(prefixedInput[it+nCoefficients:it+nCoefficients*2+1])#[::-1]) 
346
+
347
+            # Summing two column vectors
348
+            powerVector = S["alpha"]*(regressorDCT) + (1.-S["alpha"])*(powerVector)
349
+            #pylab.cla()
350
+            #pylab.plot(powerVector)
351
+            #pylab.draw()
352
+
353
+            outputVector[it] = np.dot(coefficientVectorDCT.T, regressorDCT)
354
+            #errorVector[it] = desired[it] - outputVector[it]
355
+            errorVector[it] = desiredDCT[it] - outputVector[it]
356
+
357
+            # Vectorized
358
+            coefficientVectorDCT += (S["step"]*errorVector[it]*regressorDCT) #/\
359
+                                    #(S['gamma']+powerVector)
360
+
361
+        #pylab.plot(errorVector)
362
+        #pylab.show()
363
+        return dct(errorVector, type=3)
364
+        #coefficientVector = ifft(coefficientVectorDCT)*sqrt(nCoefficients);
365
+
366
+
367
+
368
+    def Tdomain_CORR(self, desired, input, S):
369
+
370
+        from scipy.linalg import toeplitz
371
+        from scipy.signal import correlate
372
+
373
+        # Autocorrelation
374
+        ac = np.correlate(input, input, mode='full')
375
+        ac = ac[ac.size/2:]
376
+        R = toeplitz(ac)
377
+        
378
+        # cross correllation
379
+        r = np.correlate(desired, input, mode='full')
380
+        r = r[r.size/2:]
381
+        
382
+        #r = np.correlate(desired, input, mode='valid')
383
+        print ("R", np.shape(R))
384
+        print ("r", np.shape(r))
385
+        print ("solving")
386
+        #H = np.linalg.solve(R,r)
387
+        H = np.linalg.lstsq(R,r,rcond=.01)[0]
388
+        #return desired - np.dot(H,input)
389
+        print ("done solving")
390
+        pylab.figure()
391
+        pylab.plot(H)
392
+        pylab.title("H")
393
+        #return desired - np.convolve(H, input, mode='valid')
394
+        #return desired - np.convolve(H, input, mode='same')
395
+        #return np.convolve(H, input, mode='same')
396
+        return desired - np.dot(toeplitz(H), input)
397
+        #return np.dot(R, H)
398
+
399
+#         T = toeplitz(input)
400
+#         print "shapes", np.shape(T), np.shape(desired)
401
+#         h = np.linalg.lstsq(T, desired)[0]
402
+#         print "shapes", np.shape(h), np.shape(input)
403
+#         #return np.convolve(h, input, mode='same')
404
+#         return desired - np.dot(T,h)
405
+ 
406
+    def Fdomain_CORR(self, desired, input, dt, freq):
407
+        
408
+        from scipy.linalg import toeplitz
409
+        
410
+        # Fourier domain
411
+        Input = np.fft.rfft(input)
412
+        Desired = np.fft.rfft(desired)
413
+
414
+        T = toeplitz(Input)
415
+        #H = np.linalg.solve(T, Desired)
416
+        H = np.linalg.lstsq(T, Desired)[0]
417
+#         ac = np.correlate(Input, Input, mode='full')
418
+#         ac = ac[ac.size/2:]
419
+#         R = toeplitz(ac)
420
+#         
421
+#         r = np.correlate(Desired, Input, mode='full')
422
+#         r = r[r.size/2:]
423
+#         
424
+#         #r = np.correlate(desired, input, mode='valid')
425
+#         print "R", np.shape(R)
426
+#         print "r", np.shape(r)
427
+#         print "solving"
428
+#         H = np.linalg.solve(R,r)
429
+#         #H = np.linalg.lstsq(R,r)
430
+#         #return desired - np.dot(H,input)
431
+#         print "done solving"
432
+        pylab.figure()
433
+        pylab.plot(H.real)
434
+        pylab.plot(H.imag)
435
+        pylab.plot(Input.real)
436
+        pylab.plot(Input.imag)
437
+        pylab.plot(Desired.real)
438
+        pylab.plot(Desired.imag)
439
+        pylab.legend(["hr","hi","ir","ii","dr","di"])
440
+        pylab.title("H")
441
+        #return desired - np.fft.irfft(Input*H)
442
+        return np.fft.irfft(H*Input)
443
+
444
+    def Tdomain_RLS(self, desired, input, S):
445
+        """
446
+            A DFT is first performed on the data. Than a RLS algorithm is carried out 
447
+            for noise cancellation. Related to the RLS_Alt Algoritm 5.3 in  Diniz book.
448
+            The desired and input signals are assummed to be real time series data.
449
+        """
450
+
451
+        # Transform data into frequency domain
452
+        Input = np.fft.rfft(input)
453
+        Desired = np.fft.rfft(desired)
454
+
455
+        # Initialisation Procedure
456
+        nCoefficients = S["filterOrderNo"]+1
457
+        nIterations   = len(Desired)
458
+
459
+        # Pre Allocations
460
+        errorVector  = np.zeros(nIterations, dtype="complex")
461
+        outputVector = np.zeros(nIterations, dtype="complex")
462
+        errorVectorPost  = np.zeros(nIterations, dtype="complex")
463
+        outputVectorPost = np.zeros(nIterations, dtype="complex")
464
+        coefficientVector = np.zeros( (nCoefficients, nIterations+1), dtype="complex" )        
465
+
466
+        # Initial State
467
+        coefficientVector[:,1] = S["initialCoefficients"]  
468
+        S_d                    = S["delta"]*np.eye(nCoefficients)
469
+
470
+        # Improve source code regularity, pad with zeros
471
+        prefixedInput = np.concatenate([np.zeros(nCoefficients-1, dtype="complex"), 
472
+                                np.array(Input)])
473
+        invLambda = 1./S["lambda"]
474
+        
475
+        # Body
476
+        pylab.ion()
477
+        pylab.figure(11)
478
+
479
+        for it in range(nIterations):
480
+            
481
+            regressor = prefixedInput[it:it+nCoefficients][::-1]
482
+
483
+            # a priori estimated output
484
+            outputVector[it] = np.dot(coefficientVector[:,it].T, regressor)
485
+       
486
+            # a priori error
487
+            errorVector[it] = Desired[it] - outputVector[it]
488
+
489
+            psi             = np.dot(S_d, regressor)
490
+            if np.isnan(psi).any():
491
+                print ("psi", psi)
492
+                exit(1)
493
+            
494
+            pylab.cla()
495
+            #pylab.plot(psi)
496
+            pylab.plot(regressor.real)
497
+            pylab.plot(regressor.imag)
498
+            pylab.plot(coefficientVector[:,it].real)
499
+            pylab.plot(coefficientVector[:,it].imag)
500
+            pylab.legend(["rr","ri", "cr", "ci"])
501
+            pylab.draw()
502
+            raw_input("paws")
503
+
504
+            S_d             = invLambda * (S_d - np.dot(psi, psi.T)  /\
505
+                                S["lambda"] + np.dot(psi.T, regressor))
506
+
507
+            coefficientVector[:,it+1] = coefficientVector[:,it] + \
508
+                                        np.conjugate(errorVector[it])*np.dot(S_d, regressor)
509
+            # A posteriori estimated output
510
+            outputVectorPost[it]  =  np.dot(coefficientVector[:,it+1].T, regressor)
511
+
512
+            # A posteriori error
513
+            errorVectorPost[it] = Desired[it] - outputVectorPost[it]
514
+ 
515
+        errorVectorPost = np.nan_to_num(errorVectorPost)
516
+
517
+        pylab.figure(11)
518
+        print (np.shape(errorVectorPost))
519
+        pylab.plot(errorVectorPost.real)
520
+        pylab.plot(errorVectorPost.imag)
521
+        pylab.show()
522
+        print(errorVectorPost)
523
+        #return np.fft.irfft(Desired)
524
+        return np.fft.irfft(errorVectorPost)
525
+
526
+if __name__ == "__main__":
527
+
528
+    def noise(nu, t, phi):
529
+        return np.sin(nu*2.*np.pi*t + phi)
530
+
531
+    import matplotlib.pyplot as plt
532
+    print("Test driver for adaptive filtering")
533
+    Filt = AdaptiveFilter(.1)
534
+    t = np.arange(0, .5, 1e-4)
535
+    omega = 2000 * 2.*np.pi
536
+    T2 = .100
537
+    n1 = noise(60, t, .2   )
538
+    n2 = noise(61, t, .514 )
539
+    x = np.sin(omega*t)* np.exp(-t/T2) + 2.3*noise(60, t, .34) + 1.783*noise(31, t, 2.1)
540
+    e = Filt.adapt_filt_tworef(x, n1, n2, 200, .98)
541
+    plt.plot(t,  x)
542
+    plt.plot(t, n1)
543
+    plt.plot(t, n2)
544
+    plt.plot(t,  e)
545
+    plt.show()

+ 546
- 0
akvo/tressel/cadapt.pyx View File

@@ -0,0 +1,546 @@
1
+import numpy as np
2
+from numpy.linalg import lstsq
3
+from numpy.linalg import norm
4
+from numpy import fft 
5
+
6
+import pylab
7
+
8
+from scipy.signal import correlate
9
+
10
+def autocorr(x):
11
+    #result = np.correlate(x, x, mode='full')
12
+    result = correlate(x, x, mode='full')
13
+    return result[result.size/2:]
14
+
15
+class AdaptiveFilter:
16
+
17
+    def __init__(self, mu):
18
+        self.mu = mu
19
+
20
+    def adapt_filt_Ref(self, x, R, M, mu, PCA, lambda2=0.95, H0=0):
21
+        """ Taken from .m file
22
+        This function is written to allow the user to filter a input signal   
23
+        with an adaptive filter that utilizes 2 reference signals instead of  
24
+        the standard method which allows for only 1 reference signal.         
25
+        Author: Rob Clemens              Date: 3/16/06                       
26
+        Modified and ported to Python, now takes arbitray number of reference points  
27
+        """
28
+        #from akvo.tressel import pca 
29
+        import akvo.tressel.cpca as pca 
30
+
31
+        if np.shape(x) != np.shape(R[0]): # or np.shape(x) != np.shape(rx1):
32
+            print ("Error, non aligned")
33
+            exit(1)
34
+        
35
+        if PCA == "Yes":
36
+            # PCA decomposition on ref channels so signals are less related
37
+            R, K, means = pca.pca( R )
38
+        
39
+        if all(H0) == 0:
40
+            H = np.zeros( (len(R)*M))
41
+            #print ("resetting filter")
42
+        else:
43
+            H = H0
44
+        Rn = np.ones(len(R)*M) / mu 
45
+        
46
+        r_ = np.zeros( (len(R), M) ) 
47
+        e = np.zeros(len(x)) # error, desired output
48
+        ilambda = lambda2**-1
49
+        cdef int z
50
+        cdef int ir
51
+        for z in range(0, len(x)):
52
+            # Only look forwards, to avoid distorting the lates times 
53
+            # (run backwards, if opposite and you don't care about distorting very late time.)
54
+            for ir in range(len(R)):
55
+                if z < M:
56
+                    r_[ir,0:z] = R[ir][0:z]
57
+                    r_[ir,z:M] = 0 
58
+                else:
59
+                    # TODO, use np.delete and np.append to speed this up
60
+                    r_[ir,:] = R[ir][z-M:z]
61
+            # reshape            
62
+            r_n = np.reshape(r_, -1) #concatenate((r_v, r_h ))
63
+
64
+            #K      = np.dot( np.diag(Rn,0), r_n) / (lambda2 + np.dot(r_n*Rn, r_n))  # Create/update K
65
+            K      = (Rn* r_n) / (lambda2 + np.dot(r_n*Rn, r_n))  # Create/update K
66
+            e[z]   = x[z] - np.dot(r_n.T, H)             # e is the filtered signal, input - r(n) * Filter Coefs
67
+            H     += K*e[z];                             # Update Filter Coefficients
68
+            Rn     = ilambda*Rn - ilambda*np.dot(np.dot(K, r_n.T), Rn)     # Update R(n)
69
+        return e, H
70
+
71
+    def transferFunctionFFT(self, D, R, reg=1e-2):
72
+        from akvo.tressel import pca
73
+        """
74
+            Computes the transfer function (H) between a Data channel and 
75
+            a number of Reference channels. The Matrices D and R are 
76
+            expected to be in the frequency domain on input.
77
+            | R1'R1 R1'R2 R1'R3|   |h1|   |R1'D|
78
+            | R2'R1 R2'R2 R2'R3| * |h2| = |R2'D|
79
+            | R3'R1 R3'R2 R3'R3|   |h3|   |R3'D|
80
+
81
+            Returns the corrected array 
82
+        """
83
+
84
+        # PCA decomposition on ref channels so signals are less related
85
+        #transMatrix, K, means = pca.pca( np.array([rx0, rx1]))   
86
+        #RR = np.zeros(( np.shape(R[0])[0]*np.shape(R[0])[1], len(R)))
87
+#         RR = np.zeros(( len(R), np.shape(R[0])[0]*np.shape(R[0])[1] ))
88
+#         for ir in range(len(R)):
89
+#             RR[ir,:] = np.reshape(R[ir], -1)
90
+#         transMatrix, K, means = pca.pca(RR)    
91
+#         #R rx0 = transMatrix[0,:]
92
+#         # rx1 = transMatrix[1,:]
93
+#         for ir in range(len(R)):
94
+#             R[ir] = transMatrix[ir,0]
95
+
96
+        import scipy.linalg 
97
+        import akvo.tressel.pca as pca 
98
+        # Compute as many transfer functions as len(R)
99
+        # A*H = B
100
+        nref = len(R)
101
+        H = np.zeros( (np.shape(D)[1], len(R)), dtype=complex )
102
+        for iw in range(np.shape(D)[1]):
103
+            A = np.zeros( (nref, nref), dtype=complex )
104
+            B = np.zeros( (nref) , dtype=complex)
105
+            for ii in range(nref):
106
+                for jj in range(nref):
107
+                    # build A
108
+                    A[ii,jj] = np.dot(R[ii][:,iw], R[jj][:,iw])                 
109
+
110
+                # build B
111
+                B[ii] = np.dot( R[ii][:,iw], D[:,iw] )
112
+
113
+            # compute H(iw)
114
+            #linalg.solve(a,b) if a is square
115
+            #print "A", A
116
+            #print "B", B
117
+            # TODO, regularise this solve step? So as to not fit the spurious noise
118
+            #print np.shape(B), np.shape(A) 
119
+            #H[iw, :] = scipy.linalg.solve(A,B)
120
+            H[iw, :] = scipy.linalg.lstsq(A,B,cond=reg)[0]
121
+            #print "lstqt", np.shape(scipy.linalg.lstsq(A,B))
122
+            #print "solve", scipy.linalg.solve(A,B)
123
+            #H[iw,:]  = scipy.linalg.lstsq(A,B) # otherwise 
124
+                #H = np.zeros( (np.shape(D)[1], )   )
125
+        #print H #A, B
126
+        Error = np.zeros(np.shape(D), dtype=complex)
127
+        for ir in range(nref):
128
+            for q in range( np.shape(D)[0] ):
129
+                #print "dimcheck", np.shape(H[:,ir]), np.shape(R[ir][q,:] )
130
+                Error[q,:] += H[:,ir]*R[ir][q,:]
131
+        return D - Error
132
+
133
+    def adapt_filt_tworefFreq(self, x, rx0, rx1, M, lambda2=0.95):
134
+        """ Frequency domain version of above
135
+        """
136
+        from akvo.tressel import pca 
137
+
138
+        pylab.figure()
139
+        pylab.plot(rx0)
140
+        pylab.plot(rx1)
141
+
142
+        # PCA decomposition on ref channels so signals are less related
143
+        transMatrix, K, means = pca.pca( np.array([rx0, rx1]))    
144
+        rx0 = transMatrix[:,0]
145
+        rx1 = transMatrix[:,1]
146
+        
147
+        pylab.plot(rx0)
148
+        pylab.plot(rx1)
149
+        pylab.show()
150
+        exit()
151
+
152
+        if np.shape(x) != np.shape(rx0) or np.shape(x) != np.shape(rx1):
153
+            print ("Error, non aligned")
154
+            exit(1)
155
+
156
+        wx = fft.rfft(x)
157
+        wr0 = fft.rfft(rx0)
158
+        wr1 = fft.rfft(rx1)
159
+ 
160
+        H = np.zeros( (2*M), dtype=complex ) 
161
+        ident_mat = np.eye((2*M))
162
+        Rn = ident_mat / 0.1
163
+        r_v = np.zeros( (M), dtype=complex ) 
164
+        r_h = np.zeros( (M), dtype=complex ) 
165
+        e = np.zeros(len(x), dtype=complex )
166
+        ilambda = lambda2**-1
167
+
168
+        for z in range(0, len(wx)):
169
+            # TODO Padd with Zeros or truncate if M >,< arrays 
170
+            r_v = wr0[::-1][:M] 
171
+            r_h = wr1[::-1][:M] 
172
+            r_n = np.concatenate((r_v, r_h ))
173
+            K      = np.dot(Rn, r_n) / (lambda2 + np.dot(np.dot(r_n.T, Rn), r_n))  # Create/update K
174
+            e[z]   = wx[z] - np.dot(r_n,H)        # e is the filtered signal, input - r(n) * Filter Coefs
175
+            H     += K * e[z];                    # Update Filter Coefficients
176
+            Rn     = ilambda*Rn - ilambda*K*r_n.T*Rn  # Update R(n)
177
+        
178
+        return fft.irfft(e)
179
+
180
+    def iter_filt_refFreq(self, x, rx0, Ahat=.05, Bhat=.5, k=0.05):
181
+
182
+        X = np.fft.rfft(x)
183
+        X0 = np.copy(X)
184
+        RX0 = np.fft.rfft(rx0)
185
+
186
+        # step 0
187
+        Abs2HW = []
188
+        alphai =  k * (np.abs(Ahat)**2 / np.abs(Bhat)**2) 
189
+        betai  =  k * (1. / (np.abs(Bhat)**2) ) 
190
+        Hw     =  ((1.+alphai) * np.abs(X)**2 ) / (np.abs(X)**2 + betai*(np.abs(RX0)**2))
191
+        H      =  np.abs(Hw)**2
192
+        pylab.ion()
193
+        pylab.figure()
194
+        for i in range(10):
195
+            #print "alphai", alphai
196
+            #print "betai", betai
197
+            #print "Hw", Hw
198
+            alphai = k * (np.abs(Ahat)**2 / np.abs(Bhat)**2) * np.product(H, axis=0)
199
+            betai  = k * (1. / np.abs(Bhat)**2) * np.product(H, axis=0)
200
+            # update signal
201
+            Hw   =  ((1.+alphai) * np.abs(X)**2) / (np.abs(X)**2 + betai*np.abs(RX0)**2)
202
+            Hw = np.nan_to_num(Hw)
203
+            X *= Hw
204
+            H = np.vstack( (H, np.abs(Hw)**2) )
205
+            #print "Hw", Hw
206
+            pylab.cla()
207
+            pylab.plot(Hw)
208
+            #pylab.plot(np.abs(X))
209
+            #pylab.plot(np.abs(RX0))
210
+            pylab.draw()
211
+            raw_input("wait")
212
+
213
+        pylab.cla()
214
+        pylab.ioff()
215
+        #return np.fft.irfft(X0-X)
216
+        return np.fft.irfft(X)
217
+
218
+    def iter_filt_refFreq(self, x, rx0, rx1, Ahat=.1, Bhat=1., k=0.001):
219
+
220
+        X = np.fft.rfft(x)
221
+        X0 = np.copy(X)
222
+        RX0 = np.fft.rfft(rx0)
223
+        RX1 = np.fft.rfft(rx1)
224
+
225
+        # step 0
226
+        alphai =  k * (np.abs(Ahat)**2 / np.abs(Bhat)**2) 
227
+        betai  =  k * (1. / (np.abs(Bhat)**2) ) 
228
+        #Hw     =  ((1.+alphai) * np.abs(X)**2 ) / (np.abs(X)**2 + betai*(np.abs(RX0)**2))
229
+        H      =  np.ones(len(X)) # abs(Hw)**2
230
+        #pylab.ion()
231
+        #pylab.figure(334)
232
+        for i in range(1000):
233
+            #print "alphai", alphai
234
+            #print "betai", betai
235
+            #print "Hw", Hw
236
+            alphai = k * (np.abs(Ahat)**2 / np.abs(Bhat)**2) * np.product(H, axis=0)
237
+            betai  = k * (1. / np.abs(Bhat)**2) * np.product(H, axis=0)
238
+            # update signal
239
+            Hw   =  ((1.+alphai) * np.abs(X)**2) / (np.abs(X)**2 + betai*np.abs(RX0)**2)
240
+            Hw = np.nan_to_num(Hw)
241
+            X *= Hw #.conjugate
242
+            #H = np.vstack((H, np.abs(Hw)**2) )
243
+            H = np.vstack((H, np.abs(Hw)) )
244
+            #print "Hw", Hw
245
+            #pylab.cla()
246
+            #pylab.plot(Hw)
247
+            #pylab.plot(np.abs(X))
248
+            #pylab.plot(np.abs(RX0))
249
+            #pylab.draw()
250
+            #raw_input("wait")
251
+
252
+        #pylab.cla()
253
+        #pylab.ioff()
254
+        return np.fft.irfft(X0-X)
255
+        #return np.fft.irfft(X)
256
+
257
+    def Tdomain_DFT(self, desired, input, S):
258
+        """ Lifted from Adaptive filtering toolbox. Modefied to accept more than one input 
259
+            vector
260
+        """
261
+        
262
+        # Initialisation Procedure
263
+        nCoefficients =   S["filterOrderNo"]/2+1
264
+        nIterations   =   len(desired)
265
+
266
+        # Pre Allocations
267
+        errorVector  = np.zeros(nIterations, dtype='complex')
268
+        outputVector = np.zeros(nIterations, dtype='complex')
269
+        
270
+        # Initial State
271
+        coefficientVectorDFT =   np.fft.rfft(S["initialCoefficients"])/np.sqrt(float(nCoefficients))
272
+        desiredDFT           =   np.fft.rfft(desired)
273
+        powerVector          =   S["initialPower"]*np.ones(nCoefficients)
274
+
275
+        # Improve source code regularity, pad with zeros
276
+        # TODO, confirm zeros(nCoeffics) not nCoeffics-1
277
+        prefixedInput  =   np.concatenate([np.zeros(nCoefficients-1), np.array(input)])
278
+
279
+        # Body
280
+        pylab.ion()
281
+        pylab.figure(11)
282
+        for it in range(nIterations): # = 1:nIterations,
283
+            
284
+            regressorDFT = np.fft.rfft(prefixedInput[it:it+nCoefficients][::-1]) /\
285
+                           np.sqrt(float(nCoefficients))
286
+
287
+            # Summing two column vectors
288
+            powerVector = S["alpha"] * (regressorDFT*np.conjugate(regressorDFT)) + \
289
+                                  (1.-S["alpha"])*(powerVector)
290
+
291
+            pylab.cla()
292
+            #pylab.plot(prefixedInput[::-1], 'b')
293
+            #pylab.plot(prefixedInput[it:it+nCoefficients][::-1], 'g', linewidth=3)
294
+            #pylab.plot(regressorDFT.real)
295
+            #pylab.plot(regressorDFT.imag)
296
+            pylab.plot(powerVector.real)
297
+            pylab.plot(powerVector.imag)
298
+            #pylab.plot(outputVector)
299
+            #pylab.plot(errorVector.real)
300
+            #pylab.plot(errorVector.imag)
301
+            pylab.draw()
302
+            #raw_input("wait")
303
+
304
+            outputVector[it] = np.dot(coefficientVectorDFT.T, regressorDFT)
305
+
306
+            #errorVector[it] = desired[it] - outputVector[it]
307
+            errorVector[it] = desiredDFT[it] - outputVector[it]
308
+
309
+            #print errorVector[it], desired[it], outputVector[it]
310
+
311
+            # Vectorized
312
+            coefficientVectorDFT += (S["step"]*np.conjugate(errorVector[it])*regressorDFT) /\
313
+                                    (S['gamma']+powerVector)
314
+
315
+        return np.real(np.fft.irfft(errorVector))
316
+        #coefficientVector = ifft(coefficientVectorDFT)*sqrt(nCoefficients);
317
+
318
+    def Tdomain_DCT(self, desired, input, S):
319
+        """ Lifted from Adaptive filtering toolbox. Modefied to accept more than one input 
320
+            vector. Uses cosine transform
321
+        """
322
+        from scipy.fftpack import dct
323
+ 
324
+        # Initialisation Procedure
325
+        nCoefficients =   S["filterOrderNo"]+1
326
+        nIterations   =   len(desired)
327
+
328
+        # Pre Allocations
329
+        errorVector  = np.zeros(nIterations)
330
+        outputVector = np.zeros(nIterations)
331
+        
332
+        # Initial State
333
+        coefficientVectorDCT =   dct(S["initialCoefficients"]) #/np.sqrt(float(nCoefficients))
334
+        desiredDCT           =   dct(desired)
335
+        powerVector          =   S["initialPower"]*np.ones(nCoefficients)
336
+
337
+        # Improve source code regularity, pad with zeros
338
+        prefixedInput  =   np.concatenate([np.zeros(nCoefficients-1), np.array(input)])
339
+        
340
+        # Body
341
+        #pylab.figure(11)
342
+        #pylab.ion()
343
+        for it in range(0, nIterations): # = 1:nIterations,
344
+            
345
+            regressorDCT = dct(prefixedInput[it:it+nCoefficients][::-1], type=2) 
346
+            #regressorDCT = dct(prefixedInput[it+nCoefficients:it+nCoefficients*2+1])#[::-1]) 
347
+
348
+            # Summing two column vectors
349
+            powerVector = S["alpha"]*(regressorDCT) + (1.-S["alpha"])*(powerVector)
350
+            #pylab.cla()
351
+            #pylab.plot(powerVector)
352
+            #pylab.draw()
353
+
354
+            outputVector[it] = np.dot(coefficientVectorDCT.T, regressorDCT)
355
+            #errorVector[it] = desired[it] - outputVector[it]
356
+            errorVector[it] = desiredDCT[it] - outputVector[it]
357
+
358
+            # Vectorized
359
+            coefficientVectorDCT += (S["step"]*errorVector[it]*regressorDCT) #/\
360
+                                    #(S['gamma']+powerVector)
361<