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.
Files changed (106) hide show
  1. pygmi-2.2.7/LICENSE.txt +623 -0
  2. pygmi-2.2.7/MANIFEST.in +7 -0
  3. pygmi-2.2.7/PKG-INFO +47 -0
  4. pygmi-2.2.7/README.md +55 -0
  5. pygmi-2.2.7/README.rst +20 -0
  6. pygmi-2.2.7/log.txt +242 -0
  7. pygmi-2.2.7/pygmi/__init__.py +22 -0
  8. pygmi-2.2.7/pygmi/clust/__init__.py +4 -0
  9. pygmi-2.2.7/pygmi/clust/crisp_clust.py +708 -0
  10. pygmi-2.2.7/pygmi/clust/datatypes.py +65 -0
  11. pygmi-2.2.7/pygmi/clust/fuzzy_clust.py +906 -0
  12. pygmi-2.2.7/pygmi/clust/graphs.py +421 -0
  13. pygmi-2.2.7/pygmi/clust/graphtool.py +667 -0
  14. pygmi-2.2.7/pygmi/clust/menu.py +139 -0
  15. pygmi-2.2.7/pygmi/clust/var_ratio.py +92 -0
  16. pygmi-2.2.7/pygmi/clust/xie_beni.py +93 -0
  17. pygmi-2.2.7/pygmi/helpdocs/linepointer.png +0 -0
  18. pygmi-2.2.7/pygmi/helpdocs/pygmi.main.html +31 -0
  19. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.ddisp.html +15 -0
  20. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.iodefs.exportkmz.html +13 -0
  21. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.iodefs.importpicture.html +16 -0
  22. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.layer.html +17 -0
  23. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.mext.html +44 -0
  24. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.misc.rangedcopy.html +16 -0
  25. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.param.html +37 -0
  26. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.prof.html +32 -0
  27. pygmi-2.2.7/pygmi/helpdocs/pygmi.pfmod.pview.html +26 -0
  28. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.gradients.html +14 -0
  29. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.tilt.html +14 -0
  30. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.cooper.visibility.html +14 -0
  31. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datagrid.html +13 -0
  32. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datamerge.html +11 -0
  33. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.datareproj.html +11 -0
  34. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.dataprep.rtp.html +14 -0
  35. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.ginterp.html +31 -0
  36. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.igrf.html +20 -0
  37. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.normalisation.html +14 -0
  38. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.smooth.html +22 -0
  39. pygmi-2.2.7/pygmi/helpdocs/pygmi.raster.tiltdepth.html +20 -0
  40. pygmi-2.2.7/pygmi/images/Help.png +0 -0
  41. pygmi-2.2.7/pygmi/images/bringtofront.png +0 -0
  42. pygmi-2.2.7/pygmi/images/cgs2.emf +0 -0
  43. pygmi-2.2.7/pygmi/images/delete.png +0 -0
  44. pygmi-2.2.7/pygmi/images/linepointer.png +0 -0
  45. pygmi-2.2.7/pygmi/images/logo256.ico +0 -0
  46. pygmi-2.2.7/pygmi/images/logo256.png +0 -0
  47. pygmi-2.2.7/pygmi/images/pointer.png +0 -0
  48. pygmi-2.2.7/pygmi/images/pygmi.png +0 -0
  49. pygmi-2.2.7/pygmi/images/sendtoback.png +0 -0
  50. pygmi-2.2.7/pygmi/main.py +1037 -0
  51. pygmi-2.2.7/pygmi/menu_default.py +327 -0
  52. pygmi-2.2.7/pygmi/misc.py +147 -0
  53. pygmi-2.2.7/pygmi/pfmod/__init__.py +6 -0
  54. pygmi-2.2.7/pygmi/pfmod/cubes.py +1488 -0
  55. pygmi-2.2.7/pygmi/pfmod/datatypes.py +292 -0
  56. pygmi-2.2.7/pygmi/pfmod/grvmag3d.py +1265 -0
  57. pygmi-2.2.7/pygmi/pfmod/iodefs.py +1001 -0
  58. pygmi-2.2.7/pygmi/pfmod/menu.py +107 -0
  59. pygmi-2.2.7/pygmi/pfmod/misc.py +301 -0
  60. pygmi-2.2.7/pygmi/pfmod/pfmod.py +248 -0
  61. pygmi-2.2.7/pygmi/pfmod/tab_ddisp.py +425 -0
  62. pygmi-2.2.7/pygmi/pfmod/tab_layer.py +490 -0
  63. pygmi-2.2.7/pygmi/pfmod/tab_mext.py +544 -0
  64. pygmi-2.2.7/pygmi/pfmod/tab_param.py +548 -0
  65. pygmi-2.2.7/pygmi/pfmod/tab_prof.py +946 -0
  66. pygmi-2.2.7/pygmi/pfmod/tab_pview.py +740 -0
  67. pygmi-2.2.7/pygmi/raster/IGRF11.COF +1635 -0
  68. pygmi-2.2.7/pygmi/raster/__init__.py +14 -0
  69. pygmi-2.2.7/pygmi/raster/cooper.py +718 -0
  70. pygmi-2.2.7/pygmi/raster/dataprep.py +1640 -0
  71. pygmi-2.2.7/pygmi/raster/datatypes.py +123 -0
  72. pygmi-2.2.7/pygmi/raster/equation_editor.py +256 -0
  73. pygmi-2.2.7/pygmi/raster/ginterp.py +1901 -0
  74. pygmi-2.2.7/pygmi/raster/graphs.py +531 -0
  75. pygmi-2.2.7/pygmi/raster/igrf.py +860 -0
  76. pygmi-2.2.7/pygmi/raster/iodefs.py +813 -0
  77. pygmi-2.2.7/pygmi/raster/menu.py +307 -0
  78. pygmi-2.2.7/pygmi/raster/normalisation.py +187 -0
  79. pygmi-2.2.7/pygmi/raster/show_table.py +245 -0
  80. pygmi-2.2.7/pygmi/raster/smooth.py +406 -0
  81. pygmi-2.2.7/pygmi/raster/tiltdepth.py +590 -0
  82. pygmi-2.2.7/pygmi/seis/__init__.py +0 -0
  83. pygmi-2.2.7/pygmi/seis/beachball.py +751 -0
  84. pygmi-2.2.7/pygmi/seis/datatypes.py +605 -0
  85. pygmi-2.2.7/pygmi/seis/del_rec.py +410 -0
  86. pygmi-2.2.7/pygmi/seis/iodefs.py +1261 -0
  87. pygmi-2.2.7/pygmi/seis/menu.py +136 -0
  88. pygmi-2.2.7/pygmi/seis/scan_imp.py +795 -0
  89. pygmi-2.2.7/pygmi/test/__init__.py +6 -0
  90. pygmi-2.2.7/pygmi/test/pfmod.py +212 -0
  91. pygmi-2.2.7/pygmi/test/tests.py +39 -0
  92. pygmi-2.2.7/pygmi/vector/__init__.py +7 -0
  93. pygmi-2.2.7/pygmi/vector/datatypes.py +74 -0
  94. pygmi-2.2.7/pygmi/vector/graphs.py +443 -0
  95. pygmi-2.2.7/pygmi/vector/iodefs.py +345 -0
  96. pygmi-2.2.7/pygmi/vector/menu.py +127 -0
  97. pygmi-2.2.7/pygmi.egg-info/PKG-INFO +47 -0
  98. pygmi-2.2.7/pygmi.egg-info/SOURCES.txt +105 -0
  99. pygmi-2.2.7/pygmi.egg-info/dependency_links.txt +1 -0
  100. pygmi-2.2.7/pygmi.egg-info/entry_points.txt +3 -0
  101. pygmi-2.2.7/pygmi.egg-info/not-zip-safe +1 -0
  102. pygmi-2.2.7/pygmi.egg-info/requires.txt +7 -0
  103. pygmi-2.2.7/pygmi.egg-info/top_level.txt +1 -0
  104. pygmi-2.2.7/quickstart.py +35 -0
  105. pygmi-2.2.7/setup.cfg +8 -0
  106. pygmi-2.2.7/setup.py +80 -0
@@ -0,0 +1,718 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Name: cooper.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 collection of routines by Gordon Cooper
26
+
27
+ | School of Geosciences, University of the Witwatersrand
28
+ | Johannesburg, South Africa
29
+ | cooperg@geosciences.wits.ac.za
30
+ | http://www.wits.ac.za/science/geophysics/gc.htm
31
+ """
32
+
33
+ from PyQt4 import QtGui, QtCore
34
+ import numpy as np
35
+ import scipy.signal as si
36
+ import copy
37
+ import pygmi.menu_default as menu_default
38
+ from numba import jit
39
+
40
+ # data = np.array([ [1, 2, 3, 4, 5, 6, 7, 8, 9],
41
+ # [1, 2, 3, 4, 5, 7, 6, 8, 9],
42
+ # [1, 2, 3, 4, 5, 7, 6, 8, 9],
43
+ # [4, 3, 2, 1, 0, 1, 2, 9, 0],
44
+ # [4, 3, 1, 1, 0, 1, 2, 3, 4],
45
+ # [4, 3, 1, 1, 0, 1, 1, 1, 2],
46
+ # [4, 3, 1, 1, 0, 1, 2, 3, 4],
47
+ # [4, 3, 1, 1, 0, 1, 1, 1, 2],
48
+ # [4, 3, 1, 1, 0, 1, 1, 2, 2]])
49
+
50
+
51
+ class Gradients(QtGui.QDialog):
52
+ """
53
+ Class used to gather information via a GUI, for function gradients
54
+
55
+ Attributes
56
+ ----------
57
+ parent : parent
58
+ indata : dictionary
59
+ PyGMI input data in a dictionary
60
+ outdata :
61
+ PyGMI input data in a dictionary
62
+ azi : float
63
+ Azimuth/filter direction (degrees)
64
+ elev : float
65
+ Elevation (for sunshading, degrees from horizontal)
66
+ order : int
67
+ Order of DR filter - see paper. Try 1 first.
68
+ """
69
+ def __init__(self, parent):
70
+ QtGui.QDialog.__init__(self, parent)
71
+
72
+ self.parent = parent
73
+ self.indata = {}
74
+ self.outdata = {}
75
+ self.azi = 45.
76
+ self.elev = 45.
77
+ self.order = 1
78
+ self.pbar = self.parent.pbar
79
+
80
+ self.sb_order = QtGui.QSpinBox()
81
+ self.sb_azi = QtGui.QSpinBox()
82
+
83
+ self.setupui()
84
+
85
+ self.sb_azi.setValue(self.azi)
86
+ self.sb_order.setValue(self.order)
87
+
88
+ def setupui(self):
89
+ """ Setup UI """
90
+ # self.resize(289, 166)
91
+ gridlayout = QtGui.QGridLayout(self)
92
+ label_az = QtGui.QLabel()
93
+ label_or = QtGui.QLabel()
94
+ buttonbox = QtGui.QDialogButtonBox()
95
+ helpdocs = menu_default.HelpButton('pygmi.raster.cooper.gradients')
96
+
97
+ self.sb_order.setMinimum(1)
98
+ self.sb_azi.setPrefix("")
99
+ self.sb_azi.setMinimum(-360)
100
+ self.sb_azi.setMaximum(360)
101
+ buttonbox.setOrientation(QtCore.Qt.Horizontal)
102
+ buttonbox.setStandardButtons(buttonbox.Cancel | buttonbox.Ok)
103
+
104
+ self.setWindowTitle("Gradient Calculation")
105
+ label_az.setText("Azimuth")
106
+ label_or.setText("Order")
107
+
108
+ gridlayout.addWidget(label_az, 0, 0, 1, 1)
109
+ gridlayout.addWidget(self.sb_azi, 0, 1, 1, 1)
110
+ gridlayout.addWidget(label_or, 3, 0, 1, 1)
111
+ gridlayout.addWidget(self.sb_order, 3, 1, 1, 1)
112
+ gridlayout.addWidget(helpdocs, 4, 0, 1, 1)
113
+ gridlayout.addWidget(buttonbox, 4, 1, 1, 1)
114
+
115
+ buttonbox.accepted.connect(self.accept)
116
+ buttonbox.rejected.connect(self.reject)
117
+
118
+ def settings(self):
119
+ """ Settings """
120
+ temp = self.exec_()
121
+ if temp == 0:
122
+ return
123
+
124
+ self.azi = self.sb_azi.value()
125
+ self.order = self.sb_order.value()
126
+
127
+ data = copy.deepcopy(self.indata['Raster'])
128
+
129
+ for i in self.pbar.iter(range(len(data))):
130
+ data[i].data = gradients(data[i].data, self.azi, 0., self.order)
131
+
132
+ self.outdata['Raster'] = data
133
+
134
+ return True
135
+
136
+
137
+ def gradients(data, azi, elev, order):
138
+ """
139
+ Compute different gradients of image data
140
+
141
+ Compute different horizontal gradients of image data. Based on code by
142
+ Gordon Cooper.
143
+
144
+ Parameters
145
+ ----------
146
+ data : numpy array
147
+ input numy data array
148
+ azi : float
149
+ Filter direction (degrees)
150
+ elev : float
151
+ Elevation (for sunshading, degrees from horizontal)
152
+ order : int
153
+ Order of DR filter - see paper. Try 1 first.
154
+
155
+ Returns
156
+ -------
157
+ dr : float
158
+ returns derivative ratio
159
+ """
160
+ # Directional derivative
161
+
162
+ azi = azi*np.pi/180
163
+ elev = elev*np.pi/180
164
+ dx, dy = np.gradient(data)
165
+ dt1 = -dy*np.sin(azi)-dx*np.cos(azi)
166
+
167
+ # Sunshading
168
+
169
+ # cAzi = np.cos(azi)
170
+ # sAzi = np.sin(azi)
171
+ # tElev = np.tan(elev)
172
+ # top = (1.0-dx*cAzi*tElev-dy*sAzi*tElev)
173
+ # bottom = np.sqrt(1.0+dx*dx+dy*dy)+np.sqrt(1.0+tElev*tElev)
174
+ # sun = top/bottom
175
+
176
+ # Derivative ratio
177
+
178
+ dt2 = -dy*np.sin(azi+np.pi/2)-dx*np.cos(azi+np.pi/2)
179
+ dr = np.arctan2(dt1, abs(dt2)**order)
180
+
181
+ return dr
182
+
183
+
184
+ class Visibility2d(QtGui.QDialog):
185
+ """
186
+ Class used to gather information via a GUI, for function visibility2d
187
+
188
+ Attributes
189
+ ----------
190
+ parent : parent
191
+ indata : dictionary
192
+ PyGMI input data in a dictionary
193
+ outdata :
194
+ PyGMI input data in a dictionary
195
+ wsize : int
196
+ window size, must be odd
197
+ dh : float
198
+ height of observer above surface
199
+ """
200
+ def __init__(self, parent):
201
+ QtGui.QDialog.__init__(self, parent)
202
+
203
+ self.parent = parent
204
+ self.indata = {}
205
+ self.outdata = {}
206
+ self.wsize = 11
207
+ self.dh = 10
208
+ self.pbar = self.parent.pbar
209
+
210
+ self.sb_dh = QtGui.QSpinBox()
211
+ self.sb_wsize = QtGui.QSpinBox()
212
+
213
+ self.setupui()
214
+
215
+ self.sb_wsize.setValue(self.wsize)
216
+ self.sb_dh.setValue(self.dh)
217
+
218
+ def setupui(self):
219
+ """ Setup UI """
220
+ gridlayout = QtGui.QGridLayout(self)
221
+ buttonbox = QtGui.QDialogButtonBox()
222
+ helpdocs = menu_default.HelpButton('pygmi.raster.cooper.visibility')
223
+ label = QtGui.QLabel()
224
+ label_2 = QtGui.QLabel()
225
+
226
+ self.sb_dh.setMinimum(1)
227
+ self.sb_dh.setMaximum(10000)
228
+ self.sb_wsize.setPrefix("")
229
+ self.sb_wsize.setMinimum(3)
230
+ self.sb_wsize.setMaximum(100000)
231
+ self.sb_wsize.setSingleStep(2)
232
+ buttonbox.setOrientation(QtCore.Qt.Horizontal)
233
+ buttonbox.setStandardButtons(buttonbox.Cancel | buttonbox.Ok)
234
+
235
+ self.setWindowTitle("Visibility")
236
+ label.setText("Viewing Height (% std dev)")
237
+ label_2.setText("Window Size (Odd)")
238
+
239
+ gridlayout.addWidget(label_2, 0, 0, 1, 1)
240
+ gridlayout.addWidget(self.sb_wsize, 0, 1, 1, 1)
241
+ gridlayout.addWidget(label, 1, 0, 1, 1)
242
+ gridlayout.addWidget(self.sb_dh, 1, 1, 1, 1)
243
+ gridlayout.addWidget(helpdocs, 2, 0, 1, 1)
244
+ gridlayout.addWidget(buttonbox, 2, 1, 1, 1)
245
+
246
+ buttonbox.accepted.connect(self.accept)
247
+ buttonbox.rejected.connect(self.reject)
248
+
249
+ def settings(self):
250
+ """ Settings """
251
+ temp = self.exec_()
252
+ if temp == 0:
253
+ return
254
+
255
+ self.wsize = self.sb_wsize.value()
256
+ self.dh = self.sb_dh.value()
257
+
258
+ data = copy.deepcopy(self.indata['Raster'])
259
+ data2 = []
260
+
261
+ for i in range(len(data)):
262
+ self.parent.showprocesslog(data[i].dataid+':')
263
+
264
+ vtot, vstd, vsum = visibility2d(data[i].data, self.wsize,
265
+ self.dh*data[i].data.std()/100.,
266
+ self.pbar.iter)
267
+ # data[i].data = vtot
268
+ data2.append(copy.deepcopy(data[i]))
269
+ data2.append(copy.deepcopy(data[i]))
270
+ data2.append(copy.deepcopy(data[i]))
271
+ data2[-3].data = vtot
272
+ data2[-2].data = vstd
273
+ data2[-1].data = vsum
274
+ data2[-3].dataid += ' Total Visibility'
275
+ data2[-2].dataid += ' Visibility Variation'
276
+ data2[-1].dataid += ' Visibility Vector Resultant'
277
+
278
+ self.outdata['Raster'] = data2
279
+ self.parent.showprocesslog('Finished!')
280
+
281
+ return True
282
+
283
+
284
+ def visibility2d(data, wsize, dh, piter=iter):
285
+ """
286
+ Compute visibility as a textural measure
287
+
288
+ Compute vertical derivatives by calculating the visibility at different
289
+ heights above the surface (see paper)
290
+
291
+ Parameters
292
+ ----------
293
+ data : numpy array
294
+ input dataset - numpy MxN array
295
+ wsize : int
296
+ window size, must be odd
297
+ dh : float
298
+ height of observer above surface
299
+
300
+ Returns
301
+ -------
302
+ vtot : numpy array
303
+ vstd : numpy array
304
+ vsum : numpy array
305
+ """
306
+
307
+ nr, nc = np.shape(data)
308
+ wsize = abs(np.real(wsize))
309
+ w2 = int(np.floor(wsize/2))
310
+ vn = np.zeros([nr, nc])
311
+ vs = np.zeros([nr, nc])
312
+ ve = np.zeros([nr, nc])
313
+ vw = np.zeros([nr, nc])
314
+ vd1 = np.zeros([nr, nc])
315
+ vd2 = np.zeros([nr, nc])
316
+ vd3 = np.zeros([nr, nc])
317
+ vd4 = np.zeros([nr, nc])
318
+ vstd = np.zeros([nr, nc])
319
+ mask = data.mask
320
+ mean = data.mean()
321
+ data = data.data
322
+ data[mask] = mean
323
+
324
+ # self.parent.showprocesslog('NS')
325
+ for j in piter(range(nc)): # Columns
326
+ for i in range(w2, nr-w2):
327
+ dtmp = data[i-w2:i+w2+1, j]
328
+ vn[i, j] = __visible1(dtmp, wsize, w2+1, dh)
329
+ vs[i, j] = __visible2(dtmp, wsize, w2+1, dh)
330
+
331
+ # self.parent.showprocesslog('EW')
332
+ for j in piter(range(w2, nc-w2)): # Rows
333
+ for i in range(nr):
334
+ dtmp = data[i, j-w2:j+w2+1]
335
+ ve[i, j] = __visible1(dtmp, wsize, w2+1, dh)
336
+ vw[i, j] = __visible2(dtmp, wsize, w2+1, dh)
337
+
338
+ # self.parent.showprocesslog('Diag')
339
+ for j in piter(range(w2, nc-w2)):
340
+ for i in range(w2, nr-w2):
341
+ dtmp = np.zeros(wsize)
342
+ for k in range(wsize):
343
+ dtmp[k] = data[i-w2+k, j-w2+k]
344
+ vd1[i, j] = __visible1(dtmp, wsize, w2+1, dh)
345
+ vd2[i, j] = __visible2(dtmp, wsize, w2+1, dh)
346
+ dtmp = np.zeros(wsize)
347
+ for k in range(wsize):
348
+ dtmp[k] = data[i+w2-k, j-w2+k]
349
+ vd3[i, j] = __visible1(dtmp, wsize, w2+1, dh)
350
+ vd4[i, j] = __visible2(dtmp, wsize, w2+1, dh)
351
+
352
+ # self.parent.showprocesslog('Computing std of visibility')
353
+ vtot = vn+vs+ve+vw+vd1+vd2+vd3+vd4
354
+ vtot = vtot[w2:nr-w2, w2:nc-w2]
355
+
356
+ for j in piter(range(nc)):
357
+ for i in range(nr):
358
+ vstd[i, j] = np.std([vn[i, j], vs[i, j], ve[i, j], vw[i, j],
359
+ vd1[i, j], vd2[i, j], vd3[i, j],
360
+ vd4[i, j]], ddof=1)
361
+
362
+ vstd = vstd[w2:nr-w2, w2:nc-w2]
363
+
364
+ dtr = np.pi/180
365
+ c45 = np.cos(45*dtr)
366
+ s45 = np.sin(45*dtr)
367
+ vsumx = ve-vw+vd1*c45-vd2*c45+vd3*c45-vd4*c45
368
+ vsumy = vn-vs+vd1*s45-vd2*s45-vd3*s45+vd4*s45
369
+ vsum = np.sqrt(vsumx*vsumx+vsumy*vsumy)
370
+ vsum = vsum[w2:nr-w2, w2:nc-w2]
371
+
372
+ vtot = np.ma.array(vtot)
373
+ vstd = np.ma.array(vstd)
374
+ vsum = np.ma.array(vsum)
375
+ vtot.mask = mask[w2:-w2, w2:-w2]
376
+ vstd.mask = mask[w2:-w2, w2:-w2]
377
+ vsum.mask = mask[w2:-w2, w2:-w2]
378
+
379
+ return vtot, vstd, vsum
380
+
381
+
382
+ def __visible1(dat, nr, cp, dh):
383
+ """ Visible 1 """
384
+ num = 1
385
+ # d = d[d.nonzero()].tolist()
386
+
387
+ if cp < nr-1 and len(dat) > 0:
388
+ num = 2
389
+ cpn = cp-1
390
+ thetamax = float(dat[cpn+1]-dat[cpn]-dh)
391
+ for i in range(cpn+2, nr):
392
+ theta = ((dat[i]-dat[cpn]-dh)/float(i-cpn))
393
+ if theta >= thetamax:
394
+ num = num + 1
395
+ thetamax = theta
396
+
397
+ return num
398
+
399
+
400
+ def __visible2(dat, nr, cp, dh):
401
+ """ Visible 2 """
402
+ num = 0
403
+ # d = d[d.nonzero()].tolist()
404
+
405
+ if cp > 2 and len(dat) > 0:
406
+ num = 1
407
+ cpn = cp-1
408
+ thetamax = (dat[cpn-1]-dat[cpn]-dh)
409
+ for i in range(cpn-2, -1, -1):
410
+ theta = ((dat[i]-dat[cpn]-dh)/(cpn-i))
411
+ if theta >= thetamax:
412
+ num = num + 1
413
+ thetamax = theta
414
+ return num
415
+
416
+
417
+ class Tilt1(QtGui.QDialog):
418
+ """
419
+ Class used to gather information via a GUI, for function tilt1
420
+
421
+ Attributes
422
+ ----------
423
+ parent : parent
424
+ indata : dictionary
425
+ PyGMI input data in a dictionary
426
+ outdata :
427
+ PyGMI input data in a dictionary
428
+ azi : float
429
+ directional filter azimuth in degrees from East
430
+ smooth : int
431
+ size of smoothing matrix to use - must be odd input 0 for no smoothing
432
+ """
433
+ def __init__(self, parent):
434
+ QtGui.QDialog.__init__(self, parent)
435
+
436
+ self.parent = parent
437
+ self.indata = {}
438
+ self.outdata = {}
439
+ self.azi = 75
440
+ self.smooth = 0
441
+ self.pbar = self.parent.pbar
442
+
443
+ self.sb_azi = QtGui.QSpinBox()
444
+ self.sb_s = QtGui.QSpinBox()
445
+
446
+ self.setupui()
447
+
448
+ self.sb_s.setValue(self.smooth)
449
+ self.sb_azi.setValue(self.azi)
450
+
451
+ def setupui(self):
452
+ """ Setup UI """
453
+ gridlayout = QtGui.QGridLayout(self)
454
+ buttonbox = QtGui.QDialogButtonBox()
455
+ helpdocs = menu_default.HelpButton('pygmi.raster.cooper.tilt')
456
+ label = QtGui.QLabel()
457
+ label_2 = QtGui.QLabel()
458
+
459
+ buttonbox.setOrientation(QtCore.Qt.Horizontal)
460
+ buttonbox.setStandardButtons(buttonbox.Cancel | buttonbox.Ok)
461
+ self.sb_azi.setMinimum(-360)
462
+ self.sb_azi.setMaximum(360)
463
+ self.sb_azi.setProperty("value", 0)
464
+ self.sb_s.setPrefix("")
465
+ self.sb_s.setMinimum(0)
466
+ self.sb_s.setMaximum(100000)
467
+ self.sb_s.setSingleStep(1)
468
+
469
+ self.setWindowTitle("Tilt Angle")
470
+ label.setText("Azimuth (degrees from east)")
471
+ label_2.setText("Smoothing Matrix Size (Odd, 0 for None)")
472
+
473
+ gridlayout.addWidget(label_2, 0, 0, 1, 1)
474
+ gridlayout.addWidget(self.sb_s, 0, 1, 1, 1)
475
+ gridlayout.addWidget(label, 1, 0, 1, 1)
476
+ gridlayout.addWidget(self.sb_azi, 1, 1, 1, 1)
477
+ gridlayout.addWidget(helpdocs, 2, 0, 1, 1)
478
+ gridlayout.addWidget(buttonbox, 2, 1, 1, 1)
479
+
480
+ buttonbox.accepted.connect(self.accept)
481
+ buttonbox.rejected.connect(self.reject)
482
+
483
+ def settings(self):
484
+ """ Settings """
485
+ temp = self.exec_()
486
+ if temp == 0:
487
+ return
488
+
489
+ self.smooth = self.sb_s.value()
490
+ self.azi = self.sb_azi.value()
491
+
492
+ data = copy.deepcopy(self.indata['Raster'])
493
+ data2 = []
494
+
495
+ for i in self.pbar.iter(range(len(data))):
496
+ t1, th, t2, ta, tdx = tilt1(data[i].data, self.azi, self.smooth)
497
+ data2.append(copy.deepcopy(data[i]))
498
+ data2.append(copy.deepcopy(data[i]))
499
+ data2.append(copy.deepcopy(data[i]))
500
+ data2.append(copy.deepcopy(data[i]))
501
+ data2.append(copy.deepcopy(data[i]))
502
+ data2[-5].data = t1
503
+ data2[-4].data = th
504
+ data2[-3].data = t2
505
+ data2[-2].data = ta
506
+ data2[-1].data = tdx
507
+ data2[-5].dataid += ' Standard Tilt Angle'
508
+ data2[-4].dataid += ' Hyperbolic Tilt Angle'
509
+ data2[-3].dataid += ' 2nd Order Tilt Angle'
510
+ data2[-2].dataid += ' Tilt Based Directional Derivative'
511
+ data2[-1].dataid += ' Total Derivative'
512
+
513
+ for i in data2:
514
+ i.data.data[i.data.mask] = i.nullvalue
515
+
516
+ self.outdata['Raster'] = data2
517
+ return True
518
+
519
+
520
+ def tilt1(data, azi, s):
521
+ """
522
+ Tilt angle calculations
523
+
524
+ Parameters
525
+ ----------
526
+ data : numpy array
527
+ matrix of double to be filtered
528
+ azi : float
529
+ directional filter azimuth in degrees from East
530
+ s : int
531
+ size of smoothing matrix to use - must be odd input 0 for no smoothing
532
+
533
+ Returns
534
+ -------
535
+ t1 : numpy masked array
536
+ Standard tilt angle
537
+ th : numpy masked array
538
+ Hyperbolic tilt angle
539
+ t2 : numpy masked array
540
+ 2nd order tilt angle
541
+ ta : numpy masked array
542
+ Tilt Based Directional Derivative
543
+ tdx : numpy masked array
544
+ Total Derivative
545
+ """
546
+
547
+ dmin = data.min()
548
+ dmax = data.max()
549
+ dm = 0.5*(dmin+dmax)
550
+ data.data[data.mask] = dm
551
+ data[np.isnan(data)] = dm
552
+ data[np.isinf(data)] = dm
553
+ # import pdb
554
+ # pdb.set_trace()
555
+ if s > 0:
556
+ se = np.ones((s, s))/(s*s)
557
+ data2 = si.convolve2d(data, se, 'valid') # smooth
558
+ mask = si.convolve2d(data.mask, se, 'valid')
559
+ data = np.ma.array(data2, mask=mask)
560
+
561
+ nr, nc = data.shape
562
+ dtr = np.pi/180.0
563
+ azi = azi*dtr
564
+ # thresh = thresh*dtr
565
+
566
+ dy, dx = np.gradient(data)
567
+ dxtot = np.sqrt(dx*dx+dy*dy)
568
+ nmax = np.max([nr, nc])
569
+ npts = int(2**__nextpow2(nmax))
570
+ dz = vertical(data, npts, 1)
571
+ t1 = np.ma.arctan(dz/dxtot)
572
+ th = np.real(np.arctanh(np.nan_to_num(dz/dxtot)+(0+0j)))
573
+ tdx = np.real(np.ma.arctan(dxtot/abs(dz)))
574
+
575
+ dx1 = dx*np.cos(azi)+dy*np.sin(azi) # Standard directional derivative
576
+ dx2 = dx*np.cos(azi+np.pi/2)+dy*np.sin(azi+np.pi/2)
577
+ dxz = np.ma.sqrt(dx2*dx2+dz*dz)
578
+ ta = np.ma.arctan(dx1/dxz) # Tilt directional derivative
579
+
580
+ # 2nd order Tilt angle
581
+
582
+ ts = t1
583
+ if s < 3:
584
+ s = 3
585
+ se = np.ones([s, s])/(s*s)
586
+ # s2 = np.floor(s/2)
587
+ ts = si.convolve2d(t1, se, 'same')
588
+ [dxs, dys] = np.gradient(ts)
589
+ dzs = vertical(ts, npts, 1)
590
+ dxtots = np.ma.sqrt(dxs*dxs+dys*dys)
591
+ t2 = np.ma.arctan(dzs/dxtots)
592
+
593
+ # Standard tilt angle, hyperbolic tilt angle, 2nd order tilt angle,
594
+ # Tilt Based Directional Derivative, Total Derivative
595
+ t1 = np.ma.array(t1)
596
+ th = np.ma.array(th)
597
+ th.mask = t1.mask
598
+ t2 = np.ma.array(t2)
599
+ t2.mask = t1.mask
600
+ ta = np.ma.array(ta)
601
+ tdx = np.ma.array(tdx)
602
+
603
+ return t1, th, t2, ta, tdx
604
+
605
+
606
+ def __nextpow2(n):
607
+ """ nextpow2 """
608
+ m_i = np.ceil(np.log2(n))
609
+ return m_i
610
+
611
+
612
+ @jit
613
+ def vertical(data, npts=None, xint=1):
614
+ """ Vertical """
615
+
616
+ nr, nc = data.shape
617
+
618
+ if npts is None:
619
+ nmax = np.max([nr, nc])
620
+ npts = int(2**__nextpow2(nmax))
621
+
622
+ cdiff = int(np.floor((npts-nc)/2))
623
+ rdiff = int(np.floor((npts-nr)/2))
624
+ data1 = __taper2d(data, npts, nc, nr, cdiff, rdiff)
625
+ # data1 = np.pad(data, ((rdiff, cdiff), (rdiff,cdiff)), 'edge')
626
+
627
+ f = np.fft.fft2(data1)
628
+ fz = f
629
+ wn = 2.0*np.pi/(xint*(npts-1))
630
+ f = np.fft.fftshift(f)
631
+ cx = npts/2+1
632
+ cy = cx
633
+ for i in range(npts):
634
+ freqx = (i+1-cx)*wn
635
+ for j in range(npts):
636
+ freqy = (j+1-cy)*wn
637
+ freq = np.sqrt(freqx*freqx+freqy*freqy)
638
+ fz[i, j] = f[i, j]*freq
639
+ fz = np.fft.fftshift(fz)
640
+ fzinv = np.fft.ifft2(fz)
641
+ dz = np.real(fzinv[rdiff:nr+rdiff, cdiff:nc+cdiff])
642
+ return dz
643
+
644
+
645
+ def __taper2d(g, npts, n, m, ndiff, mdiff):
646
+ """ Taper 2D """
647
+
648
+ # n is cols, m is rows
649
+
650
+ npts2 = npts-1
651
+ gm = g.mean()
652
+ gf = np.zeros([npts, npts])+np.median(g-gm)
653
+ gf[mdiff:mdiff+m, ndiff:ndiff+n] = g-gm
654
+
655
+ # gf = np.pad(g-gm, ((mdiff, mdiff), (ndiff, ndiff)), 'median')
656
+
657
+ for j in range(mdiff, mdiff+m):
658
+ for i in range(ndiff):
659
+ gf[i, j] = gf[i, j]*((1+np.sin(-np.pi/2+i*np.pi/ndiff))*0.5)
660
+ gf[npts2-i, j] = gf[npts2-i, j]*((1+np.sin(-np.pi/2 +
661
+ i*np.pi/ndiff))*0.5)
662
+
663
+ for j in range(mdiff):
664
+ tmp = ((1+np.sin(-np.pi/2+j*np.pi/(mdiff)))*0.5)
665
+ for i in range(ndiff, ndiff+n):
666
+ gf[i, j] = gf[i, j]*tmp
667
+ gf[i, npts2-j-1] = gf[i, npts2-j-1]*tmp
668
+
669
+ for i in range(ndiff):
670
+ tmp = ((1+np.sin(-np.pi/2+i*np.pi/(ndiff)))*0.5)
671
+ for j in range(mdiff):
672
+ gf[i, j] = gf[i, j]*tmp
673
+ gf[npts2-i, j] = gf[npts2-i, j]*tmp
674
+
675
+ for i in range(ndiff):
676
+ tmp = ((1+np.sin(-np.pi/2+i*np.pi/(ndiff)))*0.5)
677
+ for j in range(mdiff+m-1, npts):
678
+ gf[i, j] = gf[i, j]*tmp
679
+ gf[npts2-i, j] = gf[npts2-i, j]*tmp
680
+
681
+ for j in range(mdiff+m-1, npts): # Corners
682
+ for i in range(ndiff+n-1, npts):
683
+ if ndiff == 0 or mdiff == 0:
684
+ gf[i, j] = np.nan
685
+ else:
686
+ gf[i, j] = (gf[i, j] *
687
+ np.cos((i+1-ndiff-n)*np.pi/(2*ndiff)) *
688
+ np.cos((j+1-ndiff-m)*np.pi/(2*mdiff)))
689
+
690
+ for j in range(mdiff):
691
+ for i in range(ndiff):
692
+ if ndiff == 0 or mdiff == 0:
693
+ gf[i, j] = np.nan
694
+ else:
695
+ gf[i, j] = (gf[i, j] *
696
+ np.cos((i+1-ndiff)*np.pi/(2*ndiff)) *
697
+ np.cos((j+1-ndiff)*np.pi/(2*mdiff)))
698
+
699
+ for j in range(mdiff):
700
+ for i in range(ndiff+n-1, npts):
701
+ if ndiff == 0 or mdiff == 0:
702
+ gf[i, j] = np.nan
703
+ else:
704
+ gf[i, j] = (gf[i, j] *
705
+ np.cos((i+1-ndiff-n)*np.pi/(2*ndiff)) *
706
+ np.cos((j+1-ndiff)*np.pi/(2*mdiff)))
707
+
708
+ for j in range(mdiff+m, npts):
709
+ for i in range(ndiff):
710
+ if ndiff == 0 or mdiff == 0:
711
+ gf[i, j] = np.nan
712
+ else:
713
+ gf[i, j] = (gf[i, j] *
714
+ np.cos((i+1-ndiff)*np.pi/(2*ndiff)) *
715
+ np.cos((j+1-ndiff-m)*np.pi/(2*mdiff)))
716
+
717
+
718
+ return gf