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,946 @@
1
+ # -----------------------------------------------------------------------------
2
+ # Name: tab_prof.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
+ """ Profile Display Tab Routines """
26
+
27
+ from PyQt4 import QtGui, QtCore
28
+ import numpy as np
29
+ import scipy.interpolate as si
30
+ from . import misc
31
+ from ..raster import iodefs as ir
32
+ import os
33
+
34
+ import matplotlib.pyplot as plt
35
+ from matplotlib.backends.backend_qt4agg import FigureCanvas
36
+ from matplotlib.backends.backend_qt4agg import \
37
+ NavigationToolbar2QT as NavigationToolbar
38
+
39
+
40
+ class ProfileDisplay(object):
41
+ """ Widget class to call the main interface """
42
+ def __init__(self, parent):
43
+ self.parent = parent
44
+ self.lmod1 = parent.lmod1
45
+ self.lmod2 = parent.lmod2
46
+ self.showtext = parent.showtext
47
+ self.pbar = self.parent.pbar_sub
48
+ self.viewmagnetics = True
49
+
50
+ self.userint = QtGui.QWidget()
51
+
52
+ self.mmc = MyMplCanvas(self, self.lmod1)
53
+ self.mpl_toolbar = NavigationToolbar(self.mmc, self.userint)
54
+
55
+ self.sb_profnum = QtGui.QSpinBox()
56
+ self.hs_profnum = MySlider()
57
+ self.combo_profpic = QtGui.QComboBox()
58
+ self.hs_ppic_opacity = MySlider()
59
+ self.rb_axis_datamax = QtGui.QRadioButton()
60
+ self.rb_axis_profmax = QtGui.QRadioButton()
61
+ self.rb_axis_calcmax = QtGui.QRadioButton()
62
+ self.rb_axis_custmax = QtGui.QRadioButton()
63
+ self.dsb_axis_custmin = QtGui.QDoubleSpinBox()
64
+ self.dsb_axis_custmax = QtGui.QDoubleSpinBox()
65
+ self.sb_profile_linethick = QtGui.QSpinBox()
66
+ self.lw_prof_defs = QtGui.QListWidget()
67
+ self.pb_prof_rcopy = QtGui.QPushButton()
68
+ self.pb_lbound = QtGui.QPushButton()
69
+ self.pb_export_csv = QtGui.QPushButton()
70
+
71
+ self.setupui()
72
+
73
+ def setupui(self):
74
+ """ Setup UI """
75
+ gridlayout = QtGui.QGridLayout(self.userint)
76
+ groupbox = QtGui.QGroupBox()
77
+ verticallayout = QtGui.QVBoxLayout(groupbox)
78
+
79
+ sizepolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred,
80
+ QtGui.QSizePolicy.Fixed)
81
+
82
+ self.hs_profnum.setSizePolicy(sizepolicy)
83
+ self.hs_ppic_opacity.setSizePolicy(sizepolicy)
84
+
85
+ self.lw_prof_defs.setFixedWidth(220)
86
+ self.sb_profnum.setWrapping(True)
87
+ self.sb_profnum.setMaximum(999999999)
88
+ self.hs_profnum.setOrientation(QtCore.Qt.Horizontal)
89
+ self.hs_ppic_opacity.setMaximum(255)
90
+ self.hs_ppic_opacity.setProperty("value", 255)
91
+ self.hs_ppic_opacity.setOrientation(QtCore.Qt.Horizontal)
92
+ self.hs_ppic_opacity.setTickPosition(QtGui.QSlider.TicksAbove)
93
+ self.dsb_axis_custmin.setValue(0.)
94
+ self.dsb_axis_custmax.setValue(50.)
95
+ self.dsb_axis_custmin.setMinimum(-1000000.)
96
+ self.dsb_axis_custmin.setMaximum(1000000.)
97
+ self.dsb_axis_custmax.setMinimum(-1000000.)
98
+ self.dsb_axis_custmax.setMaximum(1000000.)
99
+ self.sb_profile_linethick.setMinimum(1)
100
+ self.sb_profile_linethick.setMaximum(1000)
101
+ self.rb_axis_datamax.setChecked(True)
102
+
103
+ groupbox.setTitle("Profile Y-Axis Scale")
104
+ self.sb_profnum.setPrefix("Profile: ")
105
+ self.rb_axis_datamax.setText("Scale to dataset maximum")
106
+ self.rb_axis_profmax.setText("Scale to profile maximum")
107
+ self.rb_axis_calcmax.setText("Scale to calculated maximum")
108
+ self.rb_axis_custmax.setText("Scale to custom maximum")
109
+ self.sb_profile_linethick.setPrefix("Line Thickness: ")
110
+ self.pb_prof_rcopy.setText("Ranged Copy")
111
+ self.pb_lbound.setText("Add Lithological Boundary")
112
+ self.pb_export_csv.setText("Export Profile")
113
+
114
+ gridlayout.addWidget(self.mpl_toolbar, 0, 0, 1, 1)
115
+ gridlayout.addWidget(self.mmc, 1, 0, 9, 1)
116
+ gridlayout.addWidget(self.sb_profnum, 0, 1, 1, 1)
117
+ gridlayout.addWidget(self.hs_profnum, 1, 1, 1, 1)
118
+ gridlayout.addWidget(self.combo_profpic, 2, 1, 1, 1)
119
+ gridlayout.addWidget(self.hs_ppic_opacity, 3, 1, 1, 1)
120
+ gridlayout.addWidget(self.lw_prof_defs, 4, 1, 1, 1)
121
+ gridlayout.addWidget(self.sb_profile_linethick, 5, 1, 1, 1)
122
+ gridlayout.addWidget(groupbox, 6, 1, 1, 1)
123
+ gridlayout.addWidget(self.pb_prof_rcopy, 7, 1, 1, 1)
124
+ gridlayout.addWidget(self.pb_lbound, 8, 1, 1, 1)
125
+ gridlayout.addWidget(self.pb_export_csv, 9, 1, 1, 1)
126
+
127
+ verticallayout.addWidget(self.rb_axis_datamax)
128
+ verticallayout.addWidget(self.rb_axis_profmax)
129
+ verticallayout.addWidget(self.rb_axis_calcmax)
130
+ verticallayout.addWidget(self.rb_axis_custmax)
131
+ verticallayout.addWidget(self.dsb_axis_custmin)
132
+ verticallayout.addWidget(self.dsb_axis_custmax)
133
+
134
+ # Buttons etc
135
+ self.sb_profile_linethick.valueChanged.connect(self.width)
136
+ self.lw_prof_defs.currentItemChanged.connect(self.change_defs)
137
+ self.pb_prof_rcopy.clicked.connect(self.rcopy)
138
+ self.pb_lbound.clicked.connect(self.lbound)
139
+ self.hs_profnum.valueChanged.connect(self.hprofnum)
140
+ self.hs_profnum.sliderReleased.connect(self.hprofnum)
141
+ self.sb_profnum.valueChanged.connect(self.sprofnum)
142
+ self.rb_axis_calcmax.clicked.connect(self.rb_plot_scale)
143
+ self.rb_axis_profmax.clicked.connect(self.rb_plot_scale)
144
+ self.rb_axis_datamax.clicked.connect(self.rb_plot_scale)
145
+ self.rb_axis_custmax.clicked.connect(self.rb_plot_scale)
146
+ self.dsb_axis_custmin.valueChanged.connect(self.rb_plot_scale)
147
+ self.dsb_axis_custmax.valueChanged.connect(self.rb_plot_scale)
148
+ self.pb_export_csv.clicked.connect(self.export_csv)
149
+ self.hs_ppic_opacity.valueChanged.connect(self.profpic_hs)
150
+ self.combo_profpic.currentIndexChanged.connect(self.profpic_hs)
151
+
152
+ def change_defs(self):
153
+ """ List box in profile tab for definitions """
154
+
155
+ i = self.lw_prof_defs.currentRow()
156
+ if i == -1:
157
+ misc.update_lith_lw(self.lmod1, self.lw_prof_defs)
158
+ i = 0
159
+ itxt = str(self.lw_prof_defs.item(i).text())
160
+
161
+ if itxt not in self.lmod1.lith_list.keys():
162
+ return
163
+
164
+ lith = self.lmod1.lith_list[itxt]
165
+ self.mmc.curmodel = lith.lith_index
166
+
167
+ def change_model(self, slide=False):
168
+ """ Change Model """
169
+
170
+ bottom = self.lmod1.zrange[0]
171
+ top = self.lmod1.zrange[1]
172
+
173
+ # First we plot the model stuff
174
+ newprof = self.lmod1.curprof
175
+ if self.lmod1.is_ew:
176
+ # gtmp = self.lmod1.lith_index[:, newprof,:].T.copy()
177
+ gtmp = self.lmod1.lith_index[:, newprof, ::-1].T.copy()
178
+ left = self.lmod1.xrange[0]
179
+ right = self.lmod1.xrange[1]
180
+ else:
181
+ # gtmp = self.lmod1.lith_index[newprof,:,:].T.copy()
182
+ gtmp = self.lmod1.lith_index[newprof, :, ::-1].T.copy()
183
+ left = self.lmod1.yrange[0]
184
+ right = self.lmod1.yrange[1]
185
+
186
+ extent = (left, right, bottom, top)
187
+
188
+ ctxt = str(self.combo_profpic.currentText())
189
+ if len(self.lmod1.profpics) > 0 and ctxt != u'':
190
+ gtmpl = self.lmod1.profpics[ctxt]
191
+ opac = self.hs_ppic_opacity.value()/self.hs_ppic_opacity.maximum()
192
+ else:
193
+ gtmpl = None
194
+ opac = 1.0
195
+
196
+ if slide is True:
197
+ self.mmc.slide_grid(gtmp, gtmpl, opac)
198
+ else:
199
+ self.mmc.init_grid(gtmp, extent, gtmpl, opac)
200
+
201
+ alt = self.lmod1.zrange[1]-self.lmod1.curlayer*self.lmod1.d_z
202
+
203
+ if self.lmod1.is_ew:
204
+ self.mmc.update_line(self.lmod1.xrange, [alt, alt])
205
+ else:
206
+ self.mmc.update_line(self.lmod1.yrange, [alt, alt])
207
+
208
+ def export_csv(self):
209
+ """ Export Profile to csv """
210
+ self.parent.pbars.resetall()
211
+ filename = QtGui.QFileDialog.getSaveFileName(
212
+ self.parent, 'Save File', '.', 'Comma separated values (*.csv)')
213
+ if filename == '':
214
+ return
215
+ os.chdir(filename.rpartition('/')[0])
216
+
217
+ maggrid = self.lmod1.griddata['Calculated Magnetics'].data
218
+ grvgrid = self.lmod1.griddata['Calculated Gravity'].data
219
+ curprof = self.lmod1.curprof
220
+
221
+ if self.lmod1.is_ew:
222
+ cmag = maggrid[-curprof-1]
223
+ cgrv = grvgrid[-curprof-1]
224
+ xrng = (np.arange(cmag.shape[0])*self.lmod1.dxy +
225
+ self.lmod1.xrange[0]+self.lmod1.dxy/2.)
226
+ yrng = np.zeros_like(xrng)+self.lmod1.dxy/2.
227
+
228
+ else:
229
+ cmag = maggrid[::-1, curprof]
230
+ cgrv = grvgrid[::-1, curprof]
231
+ yrng = (np.arange(cmag.shape[0])*self.lmod1.dxy +
232
+ self.lmod1.yrange[0]+self.lmod1.dxy/2.)
233
+ xrng = np.zeros_like(yrng)+self.lmod1.dxy/2.
234
+
235
+ newdata = np.transpose([xrng, yrng, cgrv, cmag])
236
+
237
+ fno = open(filename, 'wb')
238
+ fno.write(b'"x","y","Gravity","Magnetics"\n')
239
+ np.savetxt(fno, newdata, delimiter=',')
240
+ fno.close()
241
+ self.parent.pbars.incr()
242
+ self.showtext('Profile save complete')
243
+
244
+ def lbound_dialog(self):
245
+ """ Main routine to perform actual ranged copy """
246
+ lmod1 = self.lmod1
247
+ lbnd = LithBound()
248
+ lw_lithupper = lbnd.lw_lithupper
249
+ lw_lithlower = lbnd.lw_lithlower
250
+
251
+ lw_lithupper.addItem(r'Do Not Change')
252
+ lw_lithlower.addItem(r'Do Not Change')
253
+ for i in lmod1.lith_list.keys():
254
+ lw_lithupper.addItem(i)
255
+ lw_lithlower.addItem(i)
256
+
257
+ lw_lithupper.setCurrentItem(lw_lithupper.item(0))
258
+ lw_lithlower.setCurrentItem(lw_lithlower.item(1))
259
+
260
+ tmp = lbnd.exec_()
261
+ if tmp == 0:
262
+ return
263
+
264
+ tupper = lw_lithupper.selectedItems()
265
+ tlower = lw_lithlower.selectedItems()
266
+
267
+ if tupper[0].text() == r'Do Not Change':
268
+ lithupper = -999
269
+ else:
270
+ lithupper = lmod1.lith_list[tupper[0].text()].lith_index
271
+
272
+ if tlower[0].text() == r'Do Not Change':
273
+ lithlower = -999
274
+ else:
275
+ lithlower = lmod1.lith_list[tlower[0].text()].lith_index
276
+
277
+ return lithlower, lithupper
278
+
279
+ def lbound(self):
280
+ """ Insert a lithological boundary """
281
+ curgrid = self.load_data()
282
+ if curgrid is None:
283
+ return
284
+
285
+ self.update_model()
286
+ lowerb, upperb = self.lbound_dialog()
287
+
288
+ if lowerb == -999 and upperb == -999:
289
+ return
290
+
291
+ cols = curgrid.cols
292
+ rows = curgrid.rows
293
+ tlx = curgrid.tlx
294
+ tly = curgrid.tly
295
+ d_x = curgrid.xdim
296
+ d_y = curgrid.ydim
297
+ regz = self.lmod1.zrange[1]
298
+ d_z = self.lmod1.d_z
299
+
300
+ gxrng = np.array([tlx+i*d_x for i in range(cols)])
301
+ gyrng = np.array([(tly-(rows-1)*d_y)+i*d_y for i in range(rows)])
302
+
303
+ # This section gets rid of null values quickly
304
+ xt, yt = np.meshgrid(gxrng, gyrng)
305
+ zt = curgrid.data.data
306
+ msk = np.logical_not(np.logical_or(curgrid.data.mask, np.isnan(zt)))
307
+ zt = zt[msk]
308
+ xy = np.transpose([xt[msk], yt[msk]])
309
+ xy2 = np.transpose([xt, yt])
310
+ newgrid = np.transpose(si.griddata(xy, zt, xy2, 'nearest'))
311
+
312
+ # Back to splines
313
+ fgrid = si.RectBivariateSpline(gyrng, gxrng, newgrid)
314
+
315
+ for i in range(self.lmod1.numx):
316
+ for j in range(self.lmod1.numy):
317
+ imod = i*self.lmod1.dxy+self.lmod1.xrange[0]
318
+ jmod = j*self.lmod1.dxy+self.lmod1.yrange[0]
319
+
320
+ igrd = int((imod-tlx)/d_x)
321
+ jgrd = int((tly-jmod)/d_y)
322
+
323
+ if igrd >= 0 and jgrd >= 0 and igrd < cols and jgrd < rows:
324
+ # k_2 = int((regz-fgrid.ev(jmod, imod))/d_z)
325
+ k_2 = int((regz-fgrid(jmod, imod))/d_z)
326
+ if k_2 < 0:
327
+ k_2 = 0
328
+ lfilt = self.lmod1.lith_index[i, j, k_2:] != -1
329
+ ufilt = self.lmod1.lith_index[i, j, :k_2] != -1
330
+ if lowerb != -999:
331
+ self.lmod1.lith_index[i, j, k_2:][lfilt] = lowerb
332
+ if upperb != -999:
333
+ self.lmod1.lith_index[i, j, :k_2][ufilt] = upperb
334
+
335
+ self.change_model()
336
+ self.update_plot()
337
+
338
+ def load_data(self):
339
+ """ Used to load Layer data"""
340
+ self.pbar.setMaximum(100)
341
+ self.pbar.setValue(0)
342
+
343
+ dtmp = ir.ImportData()
344
+ tmp = dtmp.settings()
345
+ if tmp is False:
346
+ return None
347
+ data = dtmp.outdata['Raster']
348
+
349
+ data[0].data = data[0].data
350
+ data[0].data = data[0].data[::-1] # need this reversed
351
+
352
+ self.pbar.setValue(100)
353
+ return data[0]
354
+
355
+ def profpic_hs(self):
356
+ """ Horizontal slider to change the profile """
357
+ self.update_model()
358
+ self.change_model(slide=True)
359
+ self.update_plot(slide=True)
360
+
361
+ def sprofnum(self):
362
+ """ Routine to change a profile from spinbox"""
363
+ self.hs_profnum.valueChanged.disconnect()
364
+ self.hs_profnum.setValue(self.sb_profnum.value())
365
+ self.hs_profnum.valueChanged.connect(self.hprofnum)
366
+
367
+ self.update_model()
368
+ self.lmod1.curprof = self.sb_profnum.value()
369
+ self.change_model(slide=True)
370
+ self.update_plot(slide=False)
371
+
372
+ def hprofnum(self):
373
+ """ Routine to change a profile from spinbox"""
374
+ self.sb_profnum.valueChanged.disconnect()
375
+ self.sb_profnum.setValue(self.hs_profnum.sliderPosition())
376
+ self.sb_profnum.valueChanged.connect(self.sprofnum)
377
+
378
+ self.update_model()
379
+ self.lmod1.curprof = self.sb_profnum.value()
380
+ self.change_model(slide=True)
381
+ self.update_plot(slide=self.hs_profnum.isSliderDown())
382
+
383
+ def rcopy(self):
384
+ """ Do a ranged copy on a profile """
385
+ self.update_model()
386
+ misc.rcopy_dialog(self.lmod1, islayer=False,
387
+ is_ew=self.lmod1.is_ew)
388
+
389
+ def update_model(self):
390
+ """ Update model itself """
391
+ if self.lmod1.is_ew:
392
+ tmp = self.lmod1.lith_index[:, self.lmod1.curprof, ::-1]
393
+ else:
394
+ tmp = self.lmod1.lith_index[self.lmod1.curprof, :, ::-1]
395
+
396
+ if tmp.shape != self.mmc.mdata.T.shape:
397
+ return
398
+
399
+ if self.lmod1.is_ew:
400
+ self.lmod1.lith_index[:, self.lmod1.curprof, ::-1] = (
401
+ self.mmc.mdata.T.copy())
402
+ else:
403
+ self.lmod1.lith_index[self.lmod1.curprof, :, ::-1] = (
404
+ self.mmc.mdata.T.copy())
405
+
406
+ def rb_plot_scale(self):
407
+ """ plot scale """
408
+ self.change_model()
409
+ self.update_plot()
410
+ self.mpl_toolbar.update()
411
+
412
+ def update_plot(self, slide=False):
413
+ """ Update the profile on the model view """
414
+
415
+ # Display the calculated profile
416
+ data = None
417
+ if self.viewmagnetics:
418
+ if 'Calculated Magnetics' in self.lmod1.griddata.keys():
419
+ data = self.lmod1.griddata['Calculated Magnetics'].data
420
+ # data2 = self.lmod2.griddata['Calculated Magnetics'].data
421
+ self.mmc.ptitle = 'Magnetic Intensity: '
422
+ self.mmc.punit = 'nT'
423
+ regtmp = 0.0
424
+ else:
425
+ if 'Calculated Gravity' in self.lmod1.griddata.keys():
426
+ data = self.lmod1.griddata['Calculated Gravity'].data
427
+ # data2 = self.lmod2.griddata['Calculated Gravity'].data
428
+ self.mmc.ptitle = 'Gravity: '
429
+ self.mmc.punit = 'mGal'
430
+ regtmp = self.lmod1.gregional
431
+
432
+ # if data2.shape != data.shape:
433
+ # data2 = np.zeros_like(data)
434
+ # alt = self.lmod1.zrange[1]-self.lmod1.curlayer*self.lmod1.d_z
435
+
436
+ if self.lmod1.is_ew and data is not None:
437
+ self.mmc.ptitle += 'West to East'
438
+ self.mmc.xlabel = "Eastings (m)"
439
+
440
+ tmpprof = data[self.lmod1.numy-1-self.lmod1.curprof, :]+regtmp
441
+ # tmpprof2 = data2[self.lmod1.curprof, :]
442
+ tmprng = (np.arange(tmpprof.shape[0])*self.lmod1.dxy +
443
+ self.lmod1.xrange[0]+self.lmod1.dxy/2.)
444
+ self.sb_profnum.setMaximum(self.lmod1.numy-1)
445
+ # self.mmc.update_line(self.lmod1.xrange, [alt, alt])
446
+ extent = self.lmod1.xrange
447
+
448
+ elif not(self.lmod1.is_ew) and data is not None:
449
+ self.mmc.ptitle += 'South to North'
450
+ self.mmc.xlabel = "Northings (m)"
451
+
452
+ tmpprof = data[::-1, self.lmod1.curprof]+regtmp
453
+ # tmpprof2 = data2[:, self.lmod1.curprof]
454
+ tmprng = (np.arange(tmpprof.shape[0])*self.lmod1.dxy +
455
+ self.lmod1.yrange[0]+self.lmod1.dxy/2.)
456
+ self.sb_profnum.setMaximum(self.lmod1.numx-1)
457
+ # self.mmc.update_line(self.lmod1.yrange, [alt, alt])
458
+ extent = self.lmod1.yrange
459
+
460
+ if self.rb_axis_custmax.isChecked():
461
+ extent = list(extent)+[self.dsb_axis_custmin.value(),
462
+ self.dsb_axis_custmax.value()]
463
+ elif self.rb_axis_calcmax.isChecked():
464
+ extent = list(extent)+[data.min()+regtmp, data.max()+regtmp]
465
+ else:
466
+ extent = list(extent)+[tmpprof.min(), tmpprof.max()]
467
+
468
+ # Load in observed data - if there is any
469
+ data2 = None
470
+ tmprng2 = None
471
+ tmpprof2 = None
472
+ if ('Magnetic Dataset' in self.lmod1.griddata.keys() and
473
+ self.viewmagnetics):
474
+ data2 = self.lmod1.griddata['Magnetic Dataset']
475
+ # regtmp = 0.0
476
+ elif ('Gravity Dataset' in self.lmod1.griddata.keys() and
477
+ not self.viewmagnetics):
478
+ data2 = self.lmod1.griddata['Gravity Dataset']
479
+ # regtmp = self.lmod1.gregional
480
+
481
+ if data2 is not None:
482
+ if self.lmod1.is_ew:
483
+ ycrdl = self.lmod1.yrange[0]+self.lmod1.curprof*self.lmod1.dxy
484
+ # ycrdl = self.lmod1.yrange[1]-self.lmod1.curprof*self.lmod1.dxy
485
+ ycrd = int((data2.tly - ycrdl)/data2.ydim)
486
+ # ycrd = data2.rows-int((data2.tly - ycrdl)/data2.ydim)
487
+
488
+ if ycrd < 0 or ycrd >= data2.rows:
489
+ if slide is False:
490
+ self.mmc.init_plot(tmprng, tmpprof, extent, tmprng2,
491
+ tmpprof2)
492
+ else:
493
+ self.mmc.slide_plot(tmprng, tmpprof, extent, tmprng2,
494
+ tmpprof2)
495
+ return
496
+ else:
497
+ tmpprof2 = data2.data[ycrd, :]
498
+ tmprng2 = (data2.tlx + np.arange(data2.cols)*data2.xdim +
499
+ data2.xdim/2)
500
+ else:
501
+ xcrdl = self.lmod1.xrange[0]+self.lmod1.curprof*self.lmod1.dxy
502
+ xcrd = int((xcrdl-data2.tlx)/data2.xdim)
503
+
504
+ if xcrd < 0 or xcrd >= data2.cols:
505
+ if slide is False:
506
+ self.mmc.init_plot(tmprng, tmpprof, extent, tmprng2,
507
+ tmpprof2)
508
+ else:
509
+ self.mmc.slide_plot(tmprng, tmpprof, extent, tmprng2,
510
+ tmpprof2)
511
+ return
512
+ else:
513
+ tmpprof2 = data2.data[::-1, xcrd]
514
+ tmprng2 = (data2.tly-data2.rows*data2.ydim +
515
+ np.arange(data2.rows)*data2.ydim + data2.ydim/2)
516
+
517
+ tmpprof2 = tmpprof2[tmprng2 >= tmprng[0]] # must be before tmprng2
518
+ tmprng2 = tmprng2[tmprng2 >= tmprng[0]]
519
+ tmpprof2 = tmpprof2[tmprng2 <= tmprng[-1]] # must bebefore tmprng2
520
+ tmprng2 = tmprng2[tmprng2 <= tmprng[-1]]
521
+
522
+ nomask = np.logical_not(tmpprof2.mask)
523
+ tmprng2 = tmprng2[nomask]
524
+ tmpprof2 = tmpprof2[nomask]
525
+
526
+ if self.rb_axis_datamax.isChecked():
527
+ extent[2:] = [data2.data.min(), data2.data.max()]
528
+ elif self.rb_axis_profmax.isChecked():
529
+ extent[2:] = [tmpprof2.min(), tmpprof2.max()]
530
+
531
+ if slide is True:
532
+ self.mmc.slide_plot(tmprng, tmpprof, extent, tmprng2, tmpprof2)
533
+ else:
534
+ self.mmc.init_plot(tmprng, tmpprof, extent, tmprng2, tmpprof2)
535
+
536
+ def width(self, width):
537
+ """ Sets the width of the edits on the profile view """
538
+
539
+ self.mmc.width = width
540
+
541
+ def tab_activate(self):
542
+ """ Runs when the tab is activated """
543
+ self.lmod1 = self.parent.lmod1
544
+ self.mmc.lmod = self.lmod1
545
+
546
+ txtmsg = ('Note: The display of gravity or magnetic data is '
547
+ 'triggered off their respective calculations. Press '
548
+ '"Calculate Gravity" to see the gravity plot and '
549
+ '"Calculate Magnetics" to see the magnetic plot')
550
+
551
+ if txtmsg not in self.parent.txtmsg.split('\n'):
552
+ self.showtext(txtmsg)
553
+
554
+ misc.update_lith_lw(self.lmod1, self.lw_prof_defs)
555
+
556
+ self.hs_profnum.valueChanged.disconnect()
557
+ self.combo_profpic.currentIndexChanged.disconnect()
558
+ self.sb_profnum.valueChanged.disconnect()
559
+
560
+ self.hs_profnum.setMinimum(0)
561
+ if self.lmod1.is_ew:
562
+ self.hs_profnum.setMaximum(self.lmod1.numy-1)
563
+ else:
564
+ self.hs_profnum.setMaximum(self.lmod1.numx-1)
565
+
566
+ if len(self.lmod1.profpics) > 0:
567
+ self.combo_profpic.clear()
568
+ self.combo_profpic.addItems(list(self.lmod1.profpics.keys()))
569
+ self.combo_profpic.setCurrentIndex(0)
570
+
571
+ self.change_model() # needs to happen before profnum set value
572
+ self.sb_profnum.setValue(self.lmod1.curprof)
573
+ self.hs_profnum.setValue(self.sb_profnum.value())
574
+ self.update_plot()
575
+ # self.change_model() # needs to happen before profnum set value
576
+ self.sb_profnum.valueChanged.connect(self.sprofnum)
577
+ self.hs_profnum.valueChanged.connect(self.hprofnum)
578
+ self.combo_profpic.currentIndexChanged.connect(self.profpic_hs)
579
+
580
+
581
+ class LithBound(QtGui.QDialog):
582
+ """ Class to call up a dialog for lithological boundary"""
583
+ def __init__(self, parent=None):
584
+ QtGui.QDialog.__init__(self, parent)
585
+
586
+ self.gridlayout = QtGui.QGridLayout(self)
587
+ self.buttonbox = QtGui.QDialogButtonBox(self)
588
+ self.lw_lithupper = QtGui.QListWidget(self)
589
+ self.lw_lithlower = QtGui.QListWidget(self)
590
+ self.label_3 = QtGui.QLabel(self)
591
+ self.label_4 = QtGui.QLabel(self)
592
+ self.setupui()
593
+
594
+ def setupui(self):
595
+ """ Setup UI """
596
+ self.gridlayout.addWidget(self.label_3, 0, 0, 1, 1)
597
+ self.lw_lithupper.setSelectionMode(
598
+ QtGui.QAbstractItemView.SingleSelection)
599
+ self.gridlayout.addWidget(self.lw_lithupper, 0, 1, 1, 1)
600
+ self.gridlayout.addWidget(self.label_4, 1, 0, 1, 1)
601
+ self.lw_lithlower.setSelectionMode(
602
+ QtGui.QAbstractItemView.SingleSelection)
603
+ self.gridlayout.addWidget(self.lw_lithlower, 1, 1, 1, 1)
604
+ self.buttonbox.setOrientation(QtCore.Qt.Horizontal)
605
+ self.buttonbox.setStandardButtons(
606
+ QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok)
607
+ self.gridlayout.addWidget(self.buttonbox, 2, 0, 1, 2)
608
+
609
+ self.setWindowTitle("Add Lithological Boundary")
610
+ self.label_3.setText("Lithologies Above Layer")
611
+ self.label_4.setText("Lithologies Below Layer")
612
+
613
+ self.buttonbox.accepted.connect(self.accept)
614
+ self.buttonbox.rejected.connect(self.reject)
615
+
616
+ # QtCore.QMetaObject.connectSlotsByName(Dialog)
617
+
618
+
619
+ class MyMplCanvas(FigureCanvas):
620
+ """This is a QWidget"""
621
+ def __init__(self, parent, lmod):
622
+ # fig = Figure()
623
+ fig = plt.figure()
624
+ FigureCanvas.__init__(self, fig)
625
+
626
+ self.parent = parent
627
+ self.lmod = lmod
628
+ self.cbar = plt.cm.jet
629
+ self.curmodel = 0
630
+ self.width = 1
631
+ self.xold = None
632
+ self.yold = None
633
+ self.press = False
634
+ self.newline = False
635
+ self.mdata = np.zeros([10, 100])
636
+ self.ptitle = ''
637
+ self.punit = ''
638
+ self.xlabel = 'Eastings (m)'
639
+ self.plotisinit = False
640
+
641
+ # Events
642
+ self.figure.canvas.mpl_connect('motion_notify_event', self.move)
643
+ self.figure.canvas.mpl_connect('button_press_event', self.button_press)
644
+ self.figure.canvas.mpl_connect('button_release_event',
645
+ self.button_release)
646
+ # Initial Images
647
+ self.paxes = fig.add_subplot(211)
648
+ self.paxes.yaxis.set_label_text("mGal")
649
+ self.paxes.ticklabel_format(useOffset=False)
650
+
651
+ self.cal = self.paxes.plot([], [])
652
+ self.obs = plt.plot([], [], '.')
653
+
654
+ self.axes = fig.add_subplot(212)
655
+ self.axes.xaxis.set_label_text(self.xlabel)
656
+ self.axes.yaxis.set_label_text("Altitude (m)")
657
+
658
+ tmp = self.cbar(self.mdata)
659
+ tmp[:, :, 3] = 0
660
+
661
+ self.ims2 = plt.imshow(tmp.copy(), interpolation='nearest',
662
+ aspect='auto')
663
+ self.ims = plt.imshow(tmp.copy(), interpolation='nearest',
664
+ aspect='auto')
665
+ self.figure.canvas.draw()
666
+
667
+ self.bbox = self.figure.canvas.copy_from_bbox(self.axes.bbox)
668
+ self.pbbox = self.figure.canvas.copy_from_bbox(self.paxes.bbox)
669
+ self.prf = self.axes.plot([0, 0])
670
+ self.figure.canvas.draw()
671
+ self.lbbox = self.figure.canvas.copy_from_bbox(self.axes.bbox)
672
+
673
+ def button_press(self, event):
674
+ """ Button press """
675
+ nmode = self.axes.get_navigate_mode()
676
+ if event.button == 1 and nmode is None:
677
+ self.press = True
678
+ self.newline = True
679
+ self.move(event)
680
+
681
+ def button_release(self, event):
682
+ """ Button press """
683
+ nmode = self.axes.get_navigate_mode()
684
+ if event.button == 1:
685
+ self.press = False
686
+ if nmode == 'ZOOM':
687
+ extent = self.axes.get_xbound()
688
+ self.paxes.set_xbound(extent[0], extent[1])
689
+ self.figure.canvas.draw()
690
+ else:
691
+ self.parent.update_model()
692
+
693
+ def move(self, event):
694
+ """ Mouse is moving """
695
+
696
+ if self.figure.canvas.toolbar._active is None:
697
+ vlim = self.axes.viewLim
698
+ if self.lmod.is_ew:
699
+ xptp = self.lmod.xrange[1]-self.lmod.xrange[0]
700
+ else:
701
+ xptp = self.lmod.yrange[1]-self.lmod.yrange[0]
702
+ yptp = self.lmod.zrange[1]-self.lmod.zrange[0]
703
+ tmp0 = self.axes.transData.transform((vlim.x0, vlim.y0))
704
+ tmp1 = self.axes.transData.transform((vlim.x1, vlim.y1))
705
+ width, height = tmp1-tmp0
706
+ width /= self.mdata.shape[1]
707
+ height /= self.mdata.shape[0]
708
+ width *= xptp/vlim.width
709
+ height *= yptp/vlim.height
710
+ cwidth = (2*self.width-1)
711
+ cb = QtGui.QBitmap(cwidth*width, cwidth*height)
712
+ cb.fill(QtCore.Qt.color1)
713
+ self.setCursor(QtGui.QCursor(cb))
714
+
715
+ dxy = self.lmod.dxy
716
+ xmin = self.lmod.xrange[0]
717
+ ymin = self.lmod.yrange[0]
718
+ zmin = self.lmod.zrange[0]
719
+
720
+ if event.inaxes == self.axes and self.press is True:
721
+ if self.lmod.is_ew:
722
+ col = int((event.xdata - xmin)/dxy)+1
723
+ else:
724
+ col = int((event.xdata - ymin)/dxy)+1
725
+ row = int((event.ydata - zmin)/self.lmod.d_z)+1
726
+
727
+ xdata = col
728
+ ydata = row
729
+
730
+ if self.newline is True:
731
+ self.newline = False
732
+ self.set_mdata(xdata, ydata)
733
+ elif xdata != self.xold:
734
+ mmm = float(ydata-self.yold)/(xdata-self.xold)
735
+ ccc = ydata - mmm * xdata
736
+ x_1 = min([self.xold, xdata])
737
+ x_2 = max([self.xold, xdata])
738
+ for i in range(x_1+1, x_2+1):
739
+ jold = int(mmm*(i-1)+ccc)
740
+ jnew = int(mmm*i+ccc)
741
+ if jold > jnew:
742
+ jold, jnew = jnew, jold
743
+ for j in range(jold, jnew+1):
744
+ self.set_mdata(i, j)
745
+
746
+ elif ydata != self.yold:
747
+ y_1 = min([self.yold, ydata])
748
+ y_2 = max([self.yold, ydata])
749
+ for j in range(y_1, y_2+1):
750
+ self.set_mdata(xdata, j)
751
+
752
+ self.xold = xdata
753
+ self.yold = ydata
754
+
755
+ self.slide_grid(self.mdata)
756
+
757
+ def set_mdata(self, xdata, ydata):
758
+ """ Routine to 'draw' the line on mdata """
759
+ gheight = self.mdata.shape[0]
760
+ gwidth = self.mdata.shape[1]
761
+
762
+ width = self.width-1 # 'pen' width
763
+ xstart = xdata-width-1
764
+ xend = xdata+width
765
+ ystart = ydata-width-1
766
+ yend = ydata+width
767
+ if xstart < 0:
768
+ xstart = 0
769
+ if xend > gwidth:
770
+ xend = gwidth
771
+ if ystart < 0:
772
+ ystart = 0
773
+ if yend > gheight:
774
+ yend = gheight
775
+
776
+ if xstart < xend and ystart < yend:
777
+ mtmp = self.mdata[ystart:yend, xstart:xend]
778
+ mtmp[np.logical_and(mtmp != -1, mtmp < 900)] = self.curmodel
779
+
780
+ def luttodat(self, dat):
781
+ """ lut to dat grid """
782
+ mlut = self.lmod.mlut
783
+ tmp = np.zeros([dat.shape[0], dat.shape[1], 4])
784
+
785
+ for i in np.unique(dat):
786
+ if i == -1:
787
+ ctmp = [0, 0, 0, 0]
788
+ else:
789
+ ctmp = np.array(mlut[i]+[255])/255.
790
+
791
+ tmp[dat[::-1] == i] = ctmp
792
+
793
+ return tmp
794
+
795
+ def init_grid(self, dat, extent, dat2, opac):
796
+ """ Updates the single color map """
797
+ # Note that because we clear the current axes, we must put the objects
798
+ # back into it are the graph will go blank on a draw(). This is the
799
+ # reason for the ims and prf commands below.
800
+
801
+ self.paxes.set_xbound(extent[0], extent[1])
802
+
803
+ self.ims.set_visible(False)
804
+ self.axes.set_xlim(extent[0], extent[1])
805
+ self.axes.set_ylim(extent[2], extent[3])
806
+
807
+ if dat2 is not None:
808
+ self.ims2.set_data(dat2.data)
809
+ self.ims2.set_extent(self.dat_extent(dat2))
810
+ self.ims2.set_clim(dat2.data.min(), dat2.data.max())
811
+
812
+ self.figure.canvas.draw()
813
+ QtGui.QApplication.processEvents()
814
+ self.bbox = self.figure.canvas.copy_from_bbox(self.axes.bbox)
815
+
816
+ self.ims.set_visible(True)
817
+ self.ims.set_extent(extent)
818
+ tmp = self.luttodat(dat)
819
+ self.ims.set_data(tmp)
820
+ self.ims.set_alpha(opac)
821
+
822
+ self.lbbox = self.figure.canvas.copy_from_bbox(self.axes.bbox)
823
+ self.figure.canvas.draw()
824
+ QtGui.QApplication.processEvents()
825
+
826
+ self.mdata = dat
827
+
828
+ def slide_grid(self, dat, dat2=None, opac=1.0):
829
+ """ Slider """
830
+ self.mdata = dat
831
+ tmp = self.luttodat(dat)
832
+ self.ims.set_data(tmp)
833
+ self.ims.set_alpha(opac)
834
+
835
+ self.figure.canvas.restore_region(self.bbox)
836
+ self.axes.draw_artist(self.ims)
837
+ self.figure.canvas.update()
838
+
839
+ self.lbbox = self.figure.canvas.copy_from_bbox(self.axes.bbox)
840
+ self.axes.draw_artist(self.prf[0])
841
+ self.figure.canvas.update()
842
+
843
+ def update_line(self, xrng, yrng):
844
+ """ Updates the line position """
845
+ self.prf[0].set_data([xrng, yrng])
846
+ self.figure.canvas.restore_region(self.lbbox)
847
+ self.axes.draw_artist(self.prf[0])
848
+ self.figure.canvas.update()
849
+
850
+ def dat_extent(self, dat):
851
+ """ Gets the extend of the dat variable """
852
+ left = dat.tlx
853
+ top = dat.tly
854
+ right = left + dat.cols*dat.xdim
855
+ bottom = top - dat.rows*dat.ydim
856
+ return (left, right, bottom, top)
857
+
858
+ # This section is just for the profile line plot
859
+
860
+ def extentchk(self, extent):
861
+ """ Checks extent """
862
+ dmin = extent[2]
863
+ dmax = extent[3]
864
+ if dmin == dmax:
865
+ dmax = dmin+1
866
+ return dmin, dmax
867
+
868
+ def init_plot(self, xdat, dat, extent, xdat2, dat2):
869
+ """ Updates the single color map """
870
+ self.paxes.autoscale(False)
871
+ dmin, dmax = self.extentchk(extent)
872
+ self.paxes.cla()
873
+ self.paxes.ticklabel_format(useOffset=False)
874
+ self.paxes.set_title(self.ptitle)
875
+ self.axes.xaxis.set_label_text(self.xlabel)
876
+ self.paxes.yaxis.set_label_text(self.punit)
877
+ self.paxes.set_ylim(dmin, dmax)
878
+ self.paxes.set_xlim(extent[0], extent[1])
879
+ self.figure.canvas.draw()
880
+ QtGui.QApplication.processEvents()
881
+ self.pbbox = self.figure.canvas.copy_from_bbox(self.paxes.bbox)
882
+
883
+ self.paxes.set_autoscalex_on(False)
884
+ self.cal = self.paxes.plot(xdat, dat)
885
+ if xdat2 is not None:
886
+ self.obs = self.paxes.plot(xdat2, dat2, '.')
887
+ else:
888
+ self.obs = self.paxes.plot([], [], '.')
889
+ self.figure.canvas.draw()
890
+ QtGui.QApplication.processEvents()
891
+ self.plotisinit = True
892
+
893
+ def slide_plot(self, xdat, dat, extent, xdat2, dat2):
894
+ """ Slider """
895
+ self.figure.canvas.restore_region(self.pbbox)
896
+ self.cal[0].set_data([xdat, dat])
897
+ if xdat2 is not None:
898
+ self.obs[0].set_data([xdat2, dat2])
899
+ else:
900
+ self.obs[0].set_data([[], []])
901
+
902
+ self.paxes.draw_artist(self.cal[0])
903
+ if xdat2 is not None:
904
+ self.paxes.draw_artist(self.obs[0])
905
+ self.figure.canvas.update()
906
+
907
+ QtGui.QApplication.processEvents()
908
+
909
+
910
+ class MySlider(QtGui.QSlider):
911
+ """
912
+ My Slider
913
+
914
+ Custom class which allows clicking on slider bar with slider moving to
915
+ click in a single step.
916
+ """
917
+ def __init__(self, parent=None):
918
+ QtGui.QPushButton.__init__(self, parent)
919
+
920
+ def mousePressEvent(self, event):
921
+ """ Mouse Press Event """
922
+ opt = QtGui.QStyleOptionSlider()
923
+ self.initStyleOption(opt)
924
+ sr = self.style()
925
+ sr = sr.subControlRect(QtGui.QStyle.CC_Slider, opt,
926
+ QtGui.QStyle.SC_SliderHandle, self)
927
+ if (event.button() == QtCore.Qt.LeftButton and
928
+ sr.contains(event.pos()) is False):
929
+ if self.orientation() == QtCore.Qt.Vertical:
930
+ self.setValue(self.minimum() + ((self.maximum()-self.minimum())
931
+ * (self.height()-event.y())) / self.height())
932
+ else:
933
+ halfHandleWidth = (0.5 * sr.width()) + 0.5
934
+ adaptedPosX = event.x()
935
+ if (adaptedPosX < halfHandleWidth):
936
+ adaptedPosX = halfHandleWidth
937
+ if (adaptedPosX > self.width() - halfHandleWidth):
938
+ adaptedPosX = self.width() - halfHandleWidth
939
+ newWidth = (self.width() - halfHandleWidth) - halfHandleWidth
940
+ normalizedPosition = (adaptedPosX-halfHandleWidth)/newWidth
941
+
942
+ newVal = self.minimum() + ((self.maximum()-self.minimum()) *
943
+ normalizedPosition)
944
+ self.setValue(newVal)
945
+ event.accept()
946
+ super(MySlider, self).mousePressEvent(event)