pygmi 2.2.7__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pygmi-2.2.7/LICENSE.txt +623 -0
- pygmi-2.2.7/MANIFEST.in +7 -0
- pygmi-2.2.7/PKG-INFO +47 -0
- pygmi-2.2.7/README.md +55 -0
- pygmi-2.2.7/README.rst +20 -0
- pygmi-2.2.7/log.txt +242 -0
- pygmi-2.2.7/pygmi/__init__.py +22 -0
- pygmi-2.2.7/pygmi/clust/__init__.py +4 -0
- pygmi-2.2.7/pygmi/clust/crisp_clust.py +708 -0
- pygmi-2.2.7/pygmi/clust/datatypes.py +65 -0
- pygmi-2.2.7/pygmi/clust/fuzzy_clust.py +906 -0
- pygmi-2.2.7/pygmi/clust/graphs.py +421 -0
- pygmi-2.2.7/pygmi/clust/graphtool.py +667 -0
- pygmi-2.2.7/pygmi/clust/menu.py +139 -0
- pygmi-2.2.7/pygmi/clust/var_ratio.py +92 -0
- pygmi-2.2.7/pygmi/clust/xie_beni.py +93 -0
- pygmi-2.2.7/pygmi/helpdocs/linepointer.png +0 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.main.html +31 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.ddisp.html +15 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.iodefs.exportkmz.html +13 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.iodefs.importpicture.html +16 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.layer.html +17 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.mext.html +44 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.misc.rangedcopy.html +16 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.param.html +37 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.prof.html +32 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.pview.html +26 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.gradients.html +14 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.tilt.html +14 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.visibility.html +14 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datagrid.html +13 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datamerge.html +11 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datareproj.html +11 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.rtp.html +14 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.ginterp.html +31 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.igrf.html +20 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.normalisation.html +14 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.smooth.html +22 -0
- pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.tiltdepth.html +20 -0
- pygmi-2.2.7/pygmi/images/Help.png +0 -0
- pygmi-2.2.7/pygmi/images/bringtofront.png +0 -0
- pygmi-2.2.7/pygmi/images/cgs2.emf +0 -0
- pygmi-2.2.7/pygmi/images/delete.png +0 -0
- pygmi-2.2.7/pygmi/images/linepointer.png +0 -0
- pygmi-2.2.7/pygmi/images/logo256.ico +0 -0
- pygmi-2.2.7/pygmi/images/logo256.png +0 -0
- pygmi-2.2.7/pygmi/images/pointer.png +0 -0
- pygmi-2.2.7/pygmi/images/pygmi.png +0 -0
- pygmi-2.2.7/pygmi/images/sendtoback.png +0 -0
- pygmi-2.2.7/pygmi/main.py +1037 -0
- pygmi-2.2.7/pygmi/menu_default.py +327 -0
- pygmi-2.2.7/pygmi/misc.py +147 -0
- pygmi-2.2.7/pygmi/pfmod/__init__.py +6 -0
- pygmi-2.2.7/pygmi/pfmod/cubes.py +1488 -0
- pygmi-2.2.7/pygmi/pfmod/datatypes.py +292 -0
- pygmi-2.2.7/pygmi/pfmod/grvmag3d.py +1265 -0
- pygmi-2.2.7/pygmi/pfmod/iodefs.py +1001 -0
- pygmi-2.2.7/pygmi/pfmod/menu.py +107 -0
- pygmi-2.2.7/pygmi/pfmod/misc.py +301 -0
- pygmi-2.2.7/pygmi/pfmod/pfmod.py +248 -0
- pygmi-2.2.7/pygmi/pfmod/tab_ddisp.py +425 -0
- pygmi-2.2.7/pygmi/pfmod/tab_layer.py +490 -0
- pygmi-2.2.7/pygmi/pfmod/tab_mext.py +544 -0
- pygmi-2.2.7/pygmi/pfmod/tab_param.py +548 -0
- pygmi-2.2.7/pygmi/pfmod/tab_prof.py +946 -0
- pygmi-2.2.7/pygmi/pfmod/tab_pview.py +740 -0
- pygmi-2.2.7/pygmi/raster/IGRF11.COF +1635 -0
- pygmi-2.2.7/pygmi/raster/__init__.py +14 -0
- pygmi-2.2.7/pygmi/raster/cooper.py +718 -0
- pygmi-2.2.7/pygmi/raster/dataprep.py +1640 -0
- pygmi-2.2.7/pygmi/raster/datatypes.py +123 -0
- pygmi-2.2.7/pygmi/raster/equation_editor.py +256 -0
- pygmi-2.2.7/pygmi/raster/ginterp.py +1901 -0
- pygmi-2.2.7/pygmi/raster/graphs.py +531 -0
- pygmi-2.2.7/pygmi/raster/igrf.py +860 -0
- pygmi-2.2.7/pygmi/raster/iodefs.py +813 -0
- pygmi-2.2.7/pygmi/raster/menu.py +307 -0
- pygmi-2.2.7/pygmi/raster/normalisation.py +187 -0
- pygmi-2.2.7/pygmi/raster/show_table.py +245 -0
- pygmi-2.2.7/pygmi/raster/smooth.py +406 -0
- pygmi-2.2.7/pygmi/raster/tiltdepth.py +590 -0
- pygmi-2.2.7/pygmi/seis/__init__.py +0 -0
- pygmi-2.2.7/pygmi/seis/beachball.py +751 -0
- pygmi-2.2.7/pygmi/seis/datatypes.py +605 -0
- pygmi-2.2.7/pygmi/seis/del_rec.py +410 -0
- pygmi-2.2.7/pygmi/seis/iodefs.py +1261 -0
- pygmi-2.2.7/pygmi/seis/menu.py +136 -0
- pygmi-2.2.7/pygmi/seis/scan_imp.py +795 -0
- pygmi-2.2.7/pygmi/test/__init__.py +6 -0
- pygmi-2.2.7/pygmi/test/pfmod.py +212 -0
- pygmi-2.2.7/pygmi/test/tests.py +39 -0
- pygmi-2.2.7/pygmi/vector/__init__.py +7 -0
- pygmi-2.2.7/pygmi/vector/datatypes.py +74 -0
- pygmi-2.2.7/pygmi/vector/graphs.py +443 -0
- pygmi-2.2.7/pygmi/vector/iodefs.py +345 -0
- pygmi-2.2.7/pygmi/vector/menu.py +127 -0
- pygmi-2.2.7/pygmi.egg-info/PKG-INFO +47 -0
- pygmi-2.2.7/pygmi.egg-info/SOURCES.txt +105 -0
- pygmi-2.2.7/pygmi.egg-info/dependency_links.txt +1 -0
- pygmi-2.2.7/pygmi.egg-info/entry_points.txt +3 -0
- pygmi-2.2.7/pygmi.egg-info/not-zip-safe +1 -0
- pygmi-2.2.7/pygmi.egg-info/requires.txt +7 -0
- pygmi-2.2.7/pygmi.egg-info/top_level.txt +1 -0
- pygmi-2.2.7/quickstart.py +35 -0
- pygmi-2.2.7/setup.cfg +8 -0
- pygmi-2.2.7/setup.py +80 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Name: show_table.py (part of PyGMI)
|
|
3
|
+
#
|
|
4
|
+
# Author: Patrick Cole
|
|
5
|
+
# E-Mail: pcole@geoscience.org.za
|
|
6
|
+
#
|
|
7
|
+
# Copyright: (c) 2013 Council for Geoscience
|
|
8
|
+
# Licence: GPL-3.0
|
|
9
|
+
#
|
|
10
|
+
# This file is part of PyGMI
|
|
11
|
+
#
|
|
12
|
+
# PyGMI is free software: you can redistribute it and/or modify
|
|
13
|
+
# it under the terms of the GNU General Public License as published by
|
|
14
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
15
|
+
# (at your option) any later version.
|
|
16
|
+
#
|
|
17
|
+
# PyGMI is distributed in the hope that it will be useful,
|
|
18
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20
|
+
# GNU General Public License for more details.
|
|
21
|
+
#
|
|
22
|
+
# You should have received a copy of the GNU General Public License
|
|
23
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
24
|
+
# -----------------------------------------------------------------------------
|
|
25
|
+
""" This is a routine which displays a table graphically with various stats """
|
|
26
|
+
|
|
27
|
+
from PyQt4 import QtGui
|
|
28
|
+
import numpy as np
|
|
29
|
+
import scipy.stats.mstats as st
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class BasicStats(QtGui.QDialog):
|
|
33
|
+
""" Show a summary of basic stats """
|
|
34
|
+
def __init__(self, parent):
|
|
35
|
+
QtGui.QDialog.__init__(self)
|
|
36
|
+
|
|
37
|
+
self.combobox = QtGui.QComboBox()
|
|
38
|
+
self.tablewidget = QtGui.QTableWidget()
|
|
39
|
+
self.pushbutton_save = QtGui.QPushButton()
|
|
40
|
+
|
|
41
|
+
self.setupui()
|
|
42
|
+
self.indata = {}
|
|
43
|
+
self.bands = None
|
|
44
|
+
self.cols = None
|
|
45
|
+
self.data = None
|
|
46
|
+
self.parent = parent
|
|
47
|
+
|
|
48
|
+
def setupui(self):
|
|
49
|
+
""" Setup UI """
|
|
50
|
+
gridlayout = QtGui.QGridLayout(self)
|
|
51
|
+
|
|
52
|
+
self.tablewidget.setRowCount(1)
|
|
53
|
+
self.tablewidget.setColumnCount(1)
|
|
54
|
+
|
|
55
|
+
self.setWindowTitle('Basic Statistics')
|
|
56
|
+
self.pushbutton_save.setText("Save")
|
|
57
|
+
|
|
58
|
+
gridlayout.addWidget(self.tablewidget, 0, 0, 2, 1)
|
|
59
|
+
gridlayout.addWidget(self.pushbutton_save, 0, 3, 1, 1)
|
|
60
|
+
gridlayout.addWidget(self.combobox, 1, 3, 1, 1)
|
|
61
|
+
|
|
62
|
+
self.combobox.currentIndexChanged.connect(self.combo)
|
|
63
|
+
self.pushbutton_save.clicked.connect(self.save)
|
|
64
|
+
|
|
65
|
+
def combo(self):
|
|
66
|
+
""" Combo """
|
|
67
|
+
i = self.combobox.currentIndex()
|
|
68
|
+
data = self.data[i][:, 1:]
|
|
69
|
+
|
|
70
|
+
for row in range(data.shape[0]):
|
|
71
|
+
for col in range(data.shape[1]):
|
|
72
|
+
self.tablewidget.setCellWidget(
|
|
73
|
+
row, col, QtGui.QLabel(str(data[row, col])))
|
|
74
|
+
|
|
75
|
+
self.tablewidget.resizeColumnsToContents()
|
|
76
|
+
|
|
77
|
+
def run(self):
|
|
78
|
+
""" run """
|
|
79
|
+
data = self.indata['Raster']
|
|
80
|
+
self.bands, self.cols, self.data = self.basicstats_calc(data)
|
|
81
|
+
|
|
82
|
+
data = self.data[0][:, 1:]
|
|
83
|
+
rows = self.data[0][:, 0]
|
|
84
|
+
cols = self.cols[1:]
|
|
85
|
+
|
|
86
|
+
if len(self.data) == 1:
|
|
87
|
+
self.combobox.hide()
|
|
88
|
+
|
|
89
|
+
self.combobox.addItems(self.bands)
|
|
90
|
+
self.tablewidget.setRowCount(data.shape[0])
|
|
91
|
+
self.tablewidget.setColumnCount(data.shape[1])
|
|
92
|
+
self.tablewidget.setHorizontalHeaderLabels(cols)
|
|
93
|
+
self.tablewidget.setVerticalHeaderLabels(rows)
|
|
94
|
+
|
|
95
|
+
self.combo()
|
|
96
|
+
self.show()
|
|
97
|
+
|
|
98
|
+
def save(self):
|
|
99
|
+
""" Save """
|
|
100
|
+
ext = "CSV Format (*.csv)"
|
|
101
|
+
filename = QtGui.QFileDialog.getSaveFileName(
|
|
102
|
+
self, 'Save Table', '.', ext)
|
|
103
|
+
if filename == '':
|
|
104
|
+
return False
|
|
105
|
+
|
|
106
|
+
ifile = str(filename)
|
|
107
|
+
savetable(ifile, self.bands, self.cols, self.data)
|
|
108
|
+
|
|
109
|
+
def basicstats_calc(self, data):
|
|
110
|
+
""" Calculate stats """
|
|
111
|
+
# Minimum, maximum, mean, std dev, median, median abs deviation
|
|
112
|
+
# no samples, no samples in x dir, no samples in y dir, band
|
|
113
|
+
stats = []
|
|
114
|
+
for i in data:
|
|
115
|
+
srow = []
|
|
116
|
+
dtmp = i.data.compressed()
|
|
117
|
+
srow.append(dtmp.min())
|
|
118
|
+
srow.append(dtmp.max())
|
|
119
|
+
srow.append(dtmp.mean())
|
|
120
|
+
srow.append(dtmp.std())
|
|
121
|
+
srow.append(np.median(dtmp))
|
|
122
|
+
srow.append(np.median(abs(dtmp - srow[-1])))
|
|
123
|
+
srow.append(i.data.size)
|
|
124
|
+
srow.append(i.data.shape[1])
|
|
125
|
+
srow.append(i.data.shape[0])
|
|
126
|
+
srow.append(st.skew(dtmp))
|
|
127
|
+
srow.append(st.kurtosis(dtmp))
|
|
128
|
+
srow = np.array(srow).tolist()
|
|
129
|
+
stats.append([i.dataid] + srow)
|
|
130
|
+
|
|
131
|
+
bands = ['Data Column']
|
|
132
|
+
cols = ['Band', 'Minimum', 'Maximum', 'Mean', 'Std Dev', 'Median',
|
|
133
|
+
'Median Abs Dev', 'No Samples', 'No cols (samples in x-dir)',
|
|
134
|
+
'No rows (samples in y-dir)', 'Skewness', 'Kurtosis']
|
|
135
|
+
dattmp = [np.array(stats, dtype=object)]
|
|
136
|
+
return bands, cols, dattmp
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class ClusterStats(QtGui.QDialog):
|
|
140
|
+
""" Show a summary of basic stats """
|
|
141
|
+
def __init__(self, parent):
|
|
142
|
+
QtGui.QDialog.__init__(self)
|
|
143
|
+
|
|
144
|
+
self.gridlayout = QtGui.QGridLayout(self)
|
|
145
|
+
self.combobox = QtGui.QComboBox(self)
|
|
146
|
+
self.tablewidget = QtGui.QTableWidget(self)
|
|
147
|
+
self.pushbutton_save = QtGui.QPushButton(self)
|
|
148
|
+
|
|
149
|
+
self.setupui()
|
|
150
|
+
self.indata = {}
|
|
151
|
+
self.data = None
|
|
152
|
+
self.cols = None
|
|
153
|
+
self.bands = None
|
|
154
|
+
self.parent = parent
|
|
155
|
+
|
|
156
|
+
def setupui(self):
|
|
157
|
+
""" Setup UI """
|
|
158
|
+
self.gridlayout.addWidget(self.tablewidget, 0, 0, 2, 1)
|
|
159
|
+
self.gridlayout.addWidget(self.pushbutton_save, 0, 3, 1, 1)
|
|
160
|
+
self.gridlayout.addWidget(self.combobox, 1, 3, 1, 1)
|
|
161
|
+
self.tablewidget.setRowCount(1)
|
|
162
|
+
self.tablewidget.setColumnCount(1)
|
|
163
|
+
|
|
164
|
+
self.setWindowTitle(
|
|
165
|
+
'Cluster Statistics (Center Value : Std Deviation)')
|
|
166
|
+
self.pushbutton_save.setText("Save")
|
|
167
|
+
|
|
168
|
+
self.combobox.currentIndexChanged.connect(self.combo)
|
|
169
|
+
self.pushbutton_save.clicked.connect(self.save)
|
|
170
|
+
|
|
171
|
+
def combo(self):
|
|
172
|
+
""" Combo """
|
|
173
|
+
i = self.combobox.currentIndex()
|
|
174
|
+
data = self.data[i]
|
|
175
|
+
|
|
176
|
+
for row in range(len(data)):
|
|
177
|
+
for col in range(len(data[0])):
|
|
178
|
+
self.tablewidget.setCellWidget(
|
|
179
|
+
row, col, QtGui.QLabel(str(data[row][col])))
|
|
180
|
+
|
|
181
|
+
self.tablewidget.resizeColumnsToContents()
|
|
182
|
+
|
|
183
|
+
def run(self):
|
|
184
|
+
""" Run """
|
|
185
|
+
self.show()
|
|
186
|
+
data = self.indata['Cluster']
|
|
187
|
+
|
|
188
|
+
self.bands = ['Clusters: ' + str(i.no_clusters) for i in data]
|
|
189
|
+
self.cols = [j for j in data[0].input_type]
|
|
190
|
+
self.data = []
|
|
191
|
+
|
|
192
|
+
for i in data:
|
|
193
|
+
val = i.center.tolist()
|
|
194
|
+
std = i.center_std.tolist()
|
|
195
|
+
for j in range(len(val)):
|
|
196
|
+
for k in range(len(val[0])):
|
|
197
|
+
val[j][k] = '{:.4f} : {:.4f}'.format(val[j][k], std[j][k])
|
|
198
|
+
self.data.append(val)
|
|
199
|
+
|
|
200
|
+
data = self.data[0]
|
|
201
|
+
rows = np.arange(1, len(self.data[0][0])+1).astype(str).tolist()
|
|
202
|
+
cols = self.cols
|
|
203
|
+
|
|
204
|
+
if len(self.data) == 1:
|
|
205
|
+
self.combobox.hide()
|
|
206
|
+
|
|
207
|
+
self.combobox.addItems(self.bands)
|
|
208
|
+
self.tablewidget.setRowCount(len(data))
|
|
209
|
+
self.tablewidget.setColumnCount(len(data[0]))
|
|
210
|
+
self.tablewidget.setHorizontalHeaderLabels(cols)
|
|
211
|
+
self.tablewidget.setVerticalHeaderLabels(rows)
|
|
212
|
+
|
|
213
|
+
self.combo()
|
|
214
|
+
|
|
215
|
+
def save(self):
|
|
216
|
+
""" Save """
|
|
217
|
+
ext = "CSV Format (*.csv)"
|
|
218
|
+
filename = QtGui.QFileDialog.getSaveFileName(
|
|
219
|
+
self, 'Save Table', '.', ext)
|
|
220
|
+
if filename == '':
|
|
221
|
+
return False
|
|
222
|
+
|
|
223
|
+
ifile = str(filename)
|
|
224
|
+
savetable(ifile, self.bands, self.cols, self.data)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def savetable(ifile, bands, cols, data):
|
|
228
|
+
""" Save tabular data """
|
|
229
|
+
fobj = open(ifile, 'a')
|
|
230
|
+
|
|
231
|
+
# htmp = 'Center'
|
|
232
|
+
htmp = cols[0]
|
|
233
|
+
for i in cols[1:]:
|
|
234
|
+
htmp += ',' + i
|
|
235
|
+
|
|
236
|
+
for k in range(len(bands)):
|
|
237
|
+
fobj.write(bands[k]+'\n')
|
|
238
|
+
fobj.write(htmp+'\n')
|
|
239
|
+
for i in range(len(data[k])):
|
|
240
|
+
rtmp = str(data[k][i][0])
|
|
241
|
+
for j in range(1, len(data[k][0])):
|
|
242
|
+
rtmp += ','+str(data[k][i][j])
|
|
243
|
+
fobj.write(rtmp+'\n')
|
|
244
|
+
fobj.write('\n')
|
|
245
|
+
fobj.close()
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# -----------------------------------------------------------------------------
|
|
2
|
+
# Name: smooth.py (part of PyGMI)
|
|
3
|
+
#
|
|
4
|
+
# Author: Patrick Cole
|
|
5
|
+
# E-Mail: pcole@geoscience.org.za
|
|
6
|
+
#
|
|
7
|
+
# Copyright: (c) 2013 Council for Geoscience
|
|
8
|
+
# Licence: GPL-3.0
|
|
9
|
+
#
|
|
10
|
+
# This file is part of PyGMI
|
|
11
|
+
#
|
|
12
|
+
# PyGMI is free software: you can redistribute it and/or modify
|
|
13
|
+
# it under the terms of the GNU General Public License as published by
|
|
14
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
15
|
+
# (at your option) any later version.
|
|
16
|
+
#
|
|
17
|
+
# PyGMI is distributed in the hope that it will be useful,
|
|
18
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
19
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
20
|
+
# GNU General Public License for more details.
|
|
21
|
+
#
|
|
22
|
+
# You should have received a copy of the GNU General Public License
|
|
23
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
24
|
+
# -----------------------------------------------------------------------------
|
|
25
|
+
""" Smooth Data """
|
|
26
|
+
|
|
27
|
+
from PyQt4 import QtGui
|
|
28
|
+
import numpy as np
|
|
29
|
+
import scipy.signal as ssig
|
|
30
|
+
import copy
|
|
31
|
+
import pygmi.menu_default as menu_default
|
|
32
|
+
# import pdb
|
|
33
|
+
# import pygmi.misc as misc
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Smooth(QtGui.QDialog):
|
|
37
|
+
""" Smooth """
|
|
38
|
+
def __init__(self, parent):
|
|
39
|
+
QtGui.QDialog.__init__(self, parent)
|
|
40
|
+
|
|
41
|
+
self.indata = {}
|
|
42
|
+
self.outdata = {}
|
|
43
|
+
self.parent = parent
|
|
44
|
+
self.pbar = parent.pbar
|
|
45
|
+
self.reportback = self.parent.showprocesslog
|
|
46
|
+
|
|
47
|
+
self.label = QtGui.QLabel()
|
|
48
|
+
self.spinbox_x = QtGui.QSpinBox()
|
|
49
|
+
self.label_2 = QtGui.QLabel()
|
|
50
|
+
self.label_3 = QtGui.QLabel()
|
|
51
|
+
self.spinbox_y = QtGui.QSpinBox()
|
|
52
|
+
self.spinbox_radius = QtGui.QSpinBox()
|
|
53
|
+
self.label_4 = QtGui.QLabel()
|
|
54
|
+
self.spinbox_stddev = QtGui.QSpinBox()
|
|
55
|
+
|
|
56
|
+
self.radiobutton_2dmedian = QtGui.QRadioButton()
|
|
57
|
+
self.radiobutton_2dmean = QtGui.QRadioButton()
|
|
58
|
+
self.radiobutton_box = QtGui.QRadioButton()
|
|
59
|
+
self.radiobutton_disk = QtGui.QRadioButton()
|
|
60
|
+
self.radiobutton_gaussian = QtGui.QRadioButton()
|
|
61
|
+
self.tablewidget = QtGui.QTableWidget()
|
|
62
|
+
|
|
63
|
+
self.setupui()
|
|
64
|
+
|
|
65
|
+
self.fmat = None
|
|
66
|
+
|
|
67
|
+
self.choosefilter()
|
|
68
|
+
|
|
69
|
+
def setupui(self):
|
|
70
|
+
""" Setup UI """
|
|
71
|
+
|
|
72
|
+
gridlayout = QtGui.QGridLayout(self)
|
|
73
|
+
groupbox = QtGui.QGroupBox()
|
|
74
|
+
gridlayout_2 = QtGui.QGridLayout(groupbox)
|
|
75
|
+
groupbox_2 = QtGui.QGroupBox()
|
|
76
|
+
groupbox_3 = QtGui.QGroupBox()
|
|
77
|
+
buttonbox = QtGui.QDialogButtonBox()
|
|
78
|
+
helpdocs = menu_default.HelpButton('pygmi.raster.smooth')
|
|
79
|
+
|
|
80
|
+
self.spinbox_x.setMinimum(1)
|
|
81
|
+
self.spinbox_x.setMaximum(999999)
|
|
82
|
+
self.spinbox_x.setProperty("value", 5)
|
|
83
|
+
self.spinbox_y.setMinimum(1)
|
|
84
|
+
self.spinbox_y.setMaximum(9999999)
|
|
85
|
+
self.spinbox_y.setProperty("value", 5)
|
|
86
|
+
self.spinbox_radius.setMinimum(1)
|
|
87
|
+
self.spinbox_radius.setMaximum(99999)
|
|
88
|
+
self.spinbox_radius.setProperty("value", 5)
|
|
89
|
+
self.spinbox_stddev.setMinimum(1)
|
|
90
|
+
self.spinbox_stddev.setMaximum(99999)
|
|
91
|
+
self.spinbox_stddev.setProperty("value", 5)
|
|
92
|
+
self.radiobutton_2dmean.setChecked(True)
|
|
93
|
+
self.radiobutton_box.setChecked(True)
|
|
94
|
+
self.tablewidget.setRowCount(5)
|
|
95
|
+
self.tablewidget.setColumnCount(5)
|
|
96
|
+
buttonbox.setStandardButtons(buttonbox.Cancel | buttonbox.Ok)
|
|
97
|
+
|
|
98
|
+
self.setWindowTitle("Smoothing Filters")
|
|
99
|
+
groupbox.setTitle("Filter Size")
|
|
100
|
+
self.label.setText("X:")
|
|
101
|
+
self.label_2.setText("Y:")
|
|
102
|
+
self.label_3.setText("Radius in Samples:")
|
|
103
|
+
self.label_4.setText("Standard Deviation:")
|
|
104
|
+
groupbox_2.setTitle("Filter Type")
|
|
105
|
+
self.radiobutton_2dmedian.setText("2D Median")
|
|
106
|
+
self.radiobutton_2dmean.setText("2D Mean")
|
|
107
|
+
groupbox_3.setTitle("Filter Shape")
|
|
108
|
+
self.radiobutton_box.setText("Box Window")
|
|
109
|
+
self.radiobutton_disk.setText("Disk Window")
|
|
110
|
+
self.radiobutton_gaussian.setText("Gaussian Window")
|
|
111
|
+
|
|
112
|
+
verticallayout = QtGui.QVBoxLayout(groupbox_2)
|
|
113
|
+
verticallayout.addWidget(self.radiobutton_2dmean)
|
|
114
|
+
verticallayout.addWidget(self.radiobutton_2dmedian)
|
|
115
|
+
verticallayout_2 = QtGui.QVBoxLayout(groupbox_3)
|
|
116
|
+
verticallayout_2.addWidget(self.radiobutton_box)
|
|
117
|
+
verticallayout_2.addWidget(self.radiobutton_disk)
|
|
118
|
+
verticallayout_2.addWidget(self.radiobutton_gaussian)
|
|
119
|
+
|
|
120
|
+
gridlayout_2.addWidget(self.label, 0, 0, 1, 1)
|
|
121
|
+
gridlayout_2.addWidget(self.spinbox_x, 0, 1, 1, 1)
|
|
122
|
+
gridlayout_2.addWidget(self.label_2, 1, 0, 1, 1)
|
|
123
|
+
gridlayout_2.addWidget(self.spinbox_y, 1, 1, 1, 1)
|
|
124
|
+
gridlayout_2.addWidget(self.label_3, 2, 0, 1, 1)
|
|
125
|
+
gridlayout_2.addWidget(self.spinbox_radius, 2, 1, 1, 1)
|
|
126
|
+
gridlayout_2.addWidget(self.label_4, 3, 0, 1, 1)
|
|
127
|
+
gridlayout_2.addWidget(self.spinbox_stddev, 3, 1, 1, 1)
|
|
128
|
+
|
|
129
|
+
gridlayout.addWidget(self.tablewidget, 1, 0, 1, 3)
|
|
130
|
+
gridlayout.addWidget(groupbox_2, 2, 0, 1, 1)
|
|
131
|
+
gridlayout.addWidget(groupbox_3, 2, 1, 1, 1)
|
|
132
|
+
gridlayout.addWidget(groupbox, 2, 2, 1, 1)
|
|
133
|
+
gridlayout.addWidget(buttonbox, 3, 1, 1, 1)
|
|
134
|
+
gridlayout.addWidget(helpdocs, 3, 0, 1, 1)
|
|
135
|
+
|
|
136
|
+
self.radiobutton_2dmean.clicked.connect(self.choosefilter)
|
|
137
|
+
self.radiobutton_2dmedian.clicked.connect(self.choosefilter)
|
|
138
|
+
self.radiobutton_box.clicked.connect(self.choosefilter)
|
|
139
|
+
self.radiobutton_disk.clicked.connect(self.choosefilter)
|
|
140
|
+
self.radiobutton_gaussian.clicked.connect(self.choosefilter)
|
|
141
|
+
self.spinbox_x.valueChanged.connect(self.choosefilter)
|
|
142
|
+
self.spinbox_y.valueChanged.connect(self.choosefilter)
|
|
143
|
+
self.spinbox_radius.valueChanged.connect(self.choosefilter)
|
|
144
|
+
self.spinbox_stddev.valueChanged.connect(self.choosefilter)
|
|
145
|
+
buttonbox.accepted.connect(self.accept)
|
|
146
|
+
buttonbox.rejected.connect(self.reject)
|
|
147
|
+
|
|
148
|
+
def settings(self):
|
|
149
|
+
""" Settings """
|
|
150
|
+
temp = self.exec_()
|
|
151
|
+
if temp == 0:
|
|
152
|
+
return
|
|
153
|
+
|
|
154
|
+
self.parent.process_is_active(True)
|
|
155
|
+
self.parent.showprocesslog('Smoothing ')
|
|
156
|
+
data = copy.deepcopy(self.indata['Raster'])
|
|
157
|
+
# if datachecks.Datachecks(self).isdata(data) is False:
|
|
158
|
+
# return data
|
|
159
|
+
# if datachecks.Datachecks(self).isnorm(data) is True:
|
|
160
|
+
# return data
|
|
161
|
+
if self.radiobutton_2dmean.isChecked():
|
|
162
|
+
for i in range(len(data)):
|
|
163
|
+
data[i].data = self.mov_win_filt(data[i].data, self.fmat,
|
|
164
|
+
'2D Mean', data[i].dataid)
|
|
165
|
+
|
|
166
|
+
if self.radiobutton_2dmedian.isChecked():
|
|
167
|
+
for i in range(len(data)):
|
|
168
|
+
data[i].data = self.mov_win_filt(data[i].data, self.fmat,
|
|
169
|
+
'2D Median', data[i].dataid)
|
|
170
|
+
|
|
171
|
+
self.parent.process_is_active(False)
|
|
172
|
+
self.outdata['Raster'] = data
|
|
173
|
+
self.parent.showprocesslog('Finished!', True)
|
|
174
|
+
|
|
175
|
+
return True
|
|
176
|
+
|
|
177
|
+
def choosefilter(self):
|
|
178
|
+
""" Section to choose the filter """
|
|
179
|
+
# Do not need to check whether inputs are greater than zero,
|
|
180
|
+
# since the spinboxes will not permit it.
|
|
181
|
+
|
|
182
|
+
box_x = self.spinbox_x.value()
|
|
183
|
+
box_y = self.spinbox_x.value()
|
|
184
|
+
rad = self.spinbox_radius.value()
|
|
185
|
+
sigma = self.spinbox_stddev.value()
|
|
186
|
+
fmat = None
|
|
187
|
+
|
|
188
|
+
if self.radiobutton_2dmean.isChecked():
|
|
189
|
+
self.radiobutton_gaussian.setVisible(True)
|
|
190
|
+
if self.radiobutton_box.isChecked():
|
|
191
|
+
fmat = filters2d('average', [box_y, box_x])
|
|
192
|
+
elif self.radiobutton_disk.isChecked():
|
|
193
|
+
fmat = filters2d('disc', rad)
|
|
194
|
+
elif self.radiobutton_gaussian.isChecked():
|
|
195
|
+
fmat = filters2d('gaussian', [box_x, box_y], sigma)
|
|
196
|
+
else:
|
|
197
|
+
self.radiobutton_gaussian.setVisible(False)
|
|
198
|
+
if self.radiobutton_gaussian.isChecked():
|
|
199
|
+
self.radiobutton_box.setChecked(True)
|
|
200
|
+
if self.radiobutton_box.isChecked():
|
|
201
|
+
fmat = np.ones((box_y, box_x))
|
|
202
|
+
elif self.radiobutton_disk.isChecked():
|
|
203
|
+
fmat = filters2d('disc', rad)
|
|
204
|
+
fmat[fmat > 0] = 1
|
|
205
|
+
|
|
206
|
+
if self.radiobutton_box.isChecked():
|
|
207
|
+
self.spinbox_x.setVisible(True)
|
|
208
|
+
self.spinbox_y.setVisible(True)
|
|
209
|
+
self.spinbox_radius.setVisible(False)
|
|
210
|
+
self.spinbox_stddev.setVisible(False)
|
|
211
|
+
self.label.setVisible(True)
|
|
212
|
+
self.label_2.setVisible(True)
|
|
213
|
+
self.label_3.setVisible(False)
|
|
214
|
+
self.label_4.setVisible(False)
|
|
215
|
+
elif self.radiobutton_disk.isChecked():
|
|
216
|
+
self.spinbox_x.setVisible(False)
|
|
217
|
+
self.spinbox_y.setVisible(False)
|
|
218
|
+
self.spinbox_radius.setVisible(True)
|
|
219
|
+
self.spinbox_stddev.setVisible(False)
|
|
220
|
+
self.label.setVisible(False)
|
|
221
|
+
self.label_2.setVisible(False)
|
|
222
|
+
self.label_3.setVisible(True)
|
|
223
|
+
self.label_4.setVisible(False)
|
|
224
|
+
elif self.radiobutton_gaussian.isChecked():
|
|
225
|
+
self.spinbox_x.setVisible(False)
|
|
226
|
+
self.spinbox_y.setVisible(False)
|
|
227
|
+
self.spinbox_radius.setVisible(False)
|
|
228
|
+
self.spinbox_stddev.setVisible(True)
|
|
229
|
+
self.label.setVisible(False)
|
|
230
|
+
self.label_2.setVisible(False)
|
|
231
|
+
self.label_3.setVisible(False)
|
|
232
|
+
self.label_4.setVisible(True)
|
|
233
|
+
|
|
234
|
+
self.fmat = fmat
|
|
235
|
+
self.updatetable()
|
|
236
|
+
|
|
237
|
+
def updatetable(self):
|
|
238
|
+
""" Update Table """
|
|
239
|
+
if self.fmat is None:
|
|
240
|
+
return
|
|
241
|
+
|
|
242
|
+
red = [0]*85 + list(range(0, 256, 3))+[255]*85
|
|
243
|
+
green = list(range(0, 256, 3)) + 85*[255] + list(range(255, 0, -3))
|
|
244
|
+
blue = [255]*85 + list(range(255, 0, -3)) + [0]*86
|
|
245
|
+
fmin = self.fmat.min()
|
|
246
|
+
frange = self.fmat.ptp()
|
|
247
|
+
|
|
248
|
+
self.tablewidget.setRowCount(self.fmat.shape[0])
|
|
249
|
+
self.tablewidget.setColumnCount(self.fmat.shape[1])
|
|
250
|
+
|
|
251
|
+
for row in range(self.fmat.shape[0]):
|
|
252
|
+
for col in range(self.fmat.shape[1]):
|
|
253
|
+
if frange == 0:
|
|
254
|
+
i = 127
|
|
255
|
+
else:
|
|
256
|
+
i = int(255*(self.fmat[row, col]-fmin)/frange)
|
|
257
|
+
ltmp = QtGui.QLabel('{:g}'.format(self.fmat[row, col]))
|
|
258
|
+
ltmp.setStyleSheet(
|
|
259
|
+
'Background: rgb' +
|
|
260
|
+
str((red[i], green[i], blue[i])) + '; Color: rgb' +
|
|
261
|
+
str((255-red[i], 255-green[i], 255-blue[i])))
|
|
262
|
+
self.tablewidget.setCellWidget(row, col, ltmp)
|
|
263
|
+
|
|
264
|
+
self.tablewidget.resizeColumnsToContents()
|
|
265
|
+
|
|
266
|
+
def msgbox(self, title, message):
|
|
267
|
+
""" Msgbox """
|
|
268
|
+
QtGui.QMessageBox.warning(self.parent, title, message,
|
|
269
|
+
QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok)
|
|
270
|
+
|
|
271
|
+
def mov_win_filt(self, dat, fmat, itype, title):
|
|
272
|
+
""" move win filt function """
|
|
273
|
+
out = dat.tolist()
|
|
274
|
+
|
|
275
|
+
rowf = fmat.shape[0]
|
|
276
|
+
colf = fmat.shape[1]
|
|
277
|
+
rowd = dat.shape[0]
|
|
278
|
+
cold = dat.shape[1]
|
|
279
|
+
drr = round(rowf/2.0)
|
|
280
|
+
dcc = round(colf/2.0)
|
|
281
|
+
|
|
282
|
+
dummy = np.zeros((rowd+rowf-1, cold+colf-1))*np.nan
|
|
283
|
+
dummy[drr-1:drr-1+rowd, dcc-1:dcc-1+cold] = dat
|
|
284
|
+
dummy = np.ma.masked_invalid(dummy)
|
|
285
|
+
dummy.mask[drr-1:drr-1+rowd, dcc-1:dcc-1+cold] = dat.mask
|
|
286
|
+
|
|
287
|
+
dummy.data[dummy.mask] = np.nan
|
|
288
|
+
dat.data[dat.mask] = np.nan
|
|
289
|
+
|
|
290
|
+
if itype == '2D Mean':
|
|
291
|
+
out = ssig.correlate(dat, fmat, 'same')
|
|
292
|
+
self.pbar.to_max()
|
|
293
|
+
|
|
294
|
+
elif itype == '2D Median':
|
|
295
|
+
self.parent.showprocesslog('Calculating Median...')
|
|
296
|
+
out = np.ma.zeros([rowd, cold])*np.nan
|
|
297
|
+
out.mask = dat.mask
|
|
298
|
+
fmat = fmat.astype(bool)
|
|
299
|
+
dummy = dummy.data
|
|
300
|
+
|
|
301
|
+
for i in self.pbar.iter(range(rowd)):
|
|
302
|
+
self.parent.showprocesslog(title+' Progress: ' +
|
|
303
|
+
str(round(100*i/rowd))+'%', True)
|
|
304
|
+
for j in range(cold):
|
|
305
|
+
tmp1 = dummy[i:i+rowf, j:j+colf][fmat]
|
|
306
|
+
if np.isnan(tmp1).min() == False:
|
|
307
|
+
out[i, j] = np.nanmedian(tmp1)
|
|
308
|
+
|
|
309
|
+
out = np.ma.masked_invalid(out)
|
|
310
|
+
out.shape = out.shape[0:2]
|
|
311
|
+
out.mask[:rowf/2] = True
|
|
312
|
+
out.mask[-rowf/2:] = True
|
|
313
|
+
out.mask[:, :colf/2] = True
|
|
314
|
+
out.mask[:, -colf/2:] = True
|
|
315
|
+
return out
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def filters2d(filtertype, sze, *sigma):
|
|
319
|
+
""" Filters 2D
|
|
320
|
+
|
|
321
|
+
These filter definitions have been translated from the octave function
|
|
322
|
+
'fspecial'.
|
|
323
|
+
|
|
324
|
+
Args:
|
|
325
|
+
filtertype (str): Type of filter. Can be 'average', 'disc' or
|
|
326
|
+
'gaussian'.
|
|
327
|
+
sze (numpy array or integer): This is a integer radius for 'disc' or a
|
|
328
|
+
vector containing rows and columns otherwize.
|
|
329
|
+
sigma (numpy array): numpy array containing std deviation. Used in
|
|
330
|
+
'gaussian'
|
|
331
|
+
|
|
332
|
+
Return:
|
|
333
|
+
numpy array: Returns the filter to be used.
|
|
334
|
+
|
|
335
|
+
Copyright (C) 2005 Peter Kovesi
|
|
336
|
+
|
|
337
|
+
This program is free software; you can redistribute it and/or modify
|
|
338
|
+
it under the terms of the GNU General Public License as published by
|
|
339
|
+
the Free Software Foundation; either version 2, or (at your option)
|
|
340
|
+
any later version.
|
|
341
|
+
|
|
342
|
+
This program is distributed in the hope that it will be useful, but
|
|
343
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
344
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
345
|
+
General Public License for more details.
|
|
346
|
+
|
|
347
|
+
You should have received a copy of the GNU General Public License
|
|
348
|
+
along with this program. If not, write to the Free Software
|
|
349
|
+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
350
|
+
02110-1301, USA.
|
|
351
|
+
|
|
352
|
+
FSPECIAL - Create spatial filters for image processing
|
|
353
|
+
|
|
354
|
+
Usage: f = fspecial(filtertype, optionalparams)
|
|
355
|
+
|
|
356
|
+
filtertype can be
|
|
357
|
+
|
|
358
|
+
| 'average' - Rectangular averaging filter
|
|
359
|
+
| 'disc' - Circular averaging filter.
|
|
360
|
+
| 'gaussian' - Gaussian filter.
|
|
361
|
+
|
|
362
|
+
The parameters that need to be specified depend on the filtertype
|
|
363
|
+
|
|
364
|
+
Examples of use and associated default values:
|
|
365
|
+
|
|
366
|
+
| f = fspecial('average',sze) sze can be a 1 or 2 vector
|
|
367
|
+
| default is [3 3].
|
|
368
|
+
| f = fspecial('disk',radius) default radius = 5
|
|
369
|
+
| f = fspecial('gaussian',sze, sigma) default sigma is 0.5
|
|
370
|
+
|
|
371
|
+
Where sze is specified as a single value the filter will be square.
|
|
372
|
+
|
|
373
|
+
| Author: Peter Kovesi <pk@csse.uwa.edu.au>
|
|
374
|
+
| Keywords: image processing, spatial filters
|
|
375
|
+
| Created: August 2005
|
|
376
|
+
"""
|
|
377
|
+
|
|
378
|
+
if filtertype == 'disc':
|
|
379
|
+
radius = sze
|
|
380
|
+
sze = [2*radius+1, 2*radius+1]
|
|
381
|
+
|
|
382
|
+
rows = sze[0]
|
|
383
|
+
cols = sze[1]
|
|
384
|
+
r2 = (rows-1)/2
|
|
385
|
+
c2 = (cols-1)/2
|
|
386
|
+
|
|
387
|
+
if filtertype == 'average':
|
|
388
|
+
rows = sze[0]
|
|
389
|
+
cols = sze[1]
|
|
390
|
+
f = np.ones(sze)/(rows*cols)
|
|
391
|
+
|
|
392
|
+
elif filtertype == 'disc':
|
|
393
|
+
[x, y] = np.mgrid[-c2: c2, -r2: r2]
|
|
394
|
+
rad = np.sqrt(x**2 + y**2)
|
|
395
|
+
f = rad <= radius
|
|
396
|
+
f = f/np.sum(f[:])
|
|
397
|
+
|
|
398
|
+
elif filtertype == 'gaussian':
|
|
399
|
+
[x, y] = np.mgrid[-c2: c2, -r2:r2]
|
|
400
|
+
radsqrd = x**2 + y**2
|
|
401
|
+
f = np.exp(-radsqrd/(2*sigma[0]**2))
|
|
402
|
+
f = f/np.sum(f[:])
|
|
403
|
+
else:
|
|
404
|
+
print('Unrecognized filter type')
|
|
405
|
+
|
|
406
|
+
return f
|