def quick_model(numx=50, numy=40, numz=5, dxy=100., d_z=100., tlx=0., tly=0., tlz=0., mht=100., ght=0., finc=-67, fdec=-17, inputliths=None, susc=None, dens=None, minc=None, mdec=None, mstrength=None, hintn=30000.): """ Create a quick model """ if inputliths is None: inputliths = ['Generic'] if susc is None: susc = [0.01] if dens is None: dens = [3.0] lmod = LithModel() lmod.update(numx, numy, numz, tlx, tly, tlz, dxy, d_z, mht, ght) lmod.lith_list['Background'] = GeoData(None, numx, numy, numz, dxy, d_z, mht, ght) lmod.lith_list['Background'].susc = 0 lmod.lith_list['Background'].density = 2.67 lmod.lith_list['Background'].finc = finc lmod.lith_list['Background'].fdec = fdec lmod.lith_list['Background'].minc = finc lmod.lith_list['Background'].mdec = fdec lmod.lith_list['Background'].hintn = hintn j = 0 if len(inputliths) == 1: clrtmp = np.array([0]) else: clrtmp = np.arange(len(inputliths))/(len(inputliths)-1) clrtmp = cm.jet(clrtmp)[:, :-1] clrtmp *= 255 clrtmp = clrtmp.astype(int) for i in inputliths: j += 1 lmod.mlut[j] = clrtmp[j-1] lmod.lith_list[i] = GeoData(None, numx, numy, numz, dxy, d_z, mht, ght) lmod.lith_list[i].susc = susc[j-1] lmod.lith_list[i].density = dens[j-1] lmod.lith_list[i].lith_index = j lmod.lith_list[i].finc = finc lmod.lith_list[i].fdec = fdec lmod.lith_list[i].hintn = hintn if mstrength is not None: lmod.lith_list[i].minc = minc[j-1] lmod.lith_list[i].mdec = mdec[j-1] lmod.lith_list[i].mstrength = mstrength[j-1] return lmod
class GravMag(object): """This class holds the generic magnetic and gravity modelling routines Routine that will calculate the final versions of the field. Other, related code is here as well, such as the inversion routines. """ def __init__(self, parent): self.parent = parent self.lmod1 = parent.lmod1 self.lmod2 = parent.lmod2 self.lmod = self.lmod1 self.showtext = parent.showtext if hasattr(parent, 'pbars'): self.pbars = parent.pbars else: self.pbars = None self.oldlithindex = None self.mfname = self.parent.modelfilename self.tmpfiles = {} self.actionregionaltest = QtWidgets.QPushButton(self.parent) self.actioncalculate = QtWidgets.QPushButton(self.parent) self.actioncalculate2 = QtWidgets.QPushButton(self.parent) self.actioncalculate3 = QtWidgets.QPushButton(self.parent) self.actioncalculate4 = QtWidgets.QPushButton(self.parent) self.setupui() def setupui(self): """ Setup UI """ self.actionregionaltest.setText("Regional Test") self.actioncalculate.setText("Calculate Gravity (All)") self.actioncalculate2.setText("Calculate Magnetics (All)") self.actioncalculate3.setText("Calculate Gravity (Changes Only)") self.actioncalculate4.setText("Calculate Magnetics (Changes Only)") self.parent.toolbar.addWidget(self.actionregionaltest) self.parent.toolbar.addSeparator() self.parent.toolbar.addWidget(self.actioncalculate) self.parent.toolbar.addWidget(self.actioncalculate2) self.parent.toolbar.addWidget(self.actioncalculate3) self.parent.toolbar.addWidget(self.actioncalculate4) self.parent.toolbar.addSeparator() self.actionregionaltest.clicked.connect(self.test_pattern) self.actioncalculate.clicked.connect(self.calc_field_grav) self.actioncalculate2.clicked.connect(self.calc_field_mag) self.actioncalculate3.clicked.connect(self.calc_field_grav_changes) self.actioncalculate4.clicked.connect(self.calc_field_mag_changes) self.actioncalculate3.setEnabled(False) self.actioncalculate4.setEnabled(False) def calc_field_mag(self): """ Pre field-calculation routine """ self.lmod1 = self.parent.lmod1 self.lmod2 = self.parent.lmod2 self.lmod = self.lmod1 self.parent.pview.viewmagnetics = True self.parent.profile.viewmagnetics = True self.lmod.lith_index_old[:] = -1 # Update the model from the view indx = self.parent.tabwidget.currentIndex() tlabel = self.parent.tabwidget.tabText(indx) if tlabel == 'Layer Editor': self.parent.layer.update_model() if tlabel == 'Profile Editor': self.parent.profile.update_model() if tlabel == 'Custom Profile Editor': self.parent.pview.update_model() # now do the calculations self.calc_field2(True, True) if tlabel == 'Profile Editor': self.parent.profile.update_plot() if tlabel == 'Custom Profile Editor': self.parent.pview.update_plot() self.actioncalculate4.setEnabled(True) def calc_field_grav(self): """ Pre field-calculation routine """ # Update this self.lmod1 = self.parent.lmod1 self.lmod2 = self.parent.lmod2 self.lmod = self.lmod1 self.parent.profile.viewmagnetics = False self.parent.pview.viewmagnetics = False self.lmod.lith_index_old[:] = -1 # Update the model from the view indx = self.parent.tabwidget.currentIndex() tlabel = self.parent.tabwidget.tabText(indx) if tlabel == 'Layer Editor': self.parent.layer.update_model() if tlabel == 'Profile Editor': self.parent.profile.update_model() if tlabel == 'Custom Profile Editor': self.parent.pview.update_model() # now do the calculations self.calc_field2(True) if tlabel == 'Profile Editor': self.parent.profile.update_plot() if tlabel == 'Custom Profile Editor': self.parent.pview.update_plot() self.actioncalculate3.setEnabled(True) def calc_field_mag_changes(self): """ calculates only mag changes """ self.lmod1 = self.parent.lmod1 self.lmod2 = self.parent.lmod2 self.lmod = self.lmod1 self.parent.pview.viewmagnetics = True self.parent.profile.viewmagnetics = True # Update the model from the view indx = self.parent.tabwidget.currentIndex() tlabel = self.parent.tabwidget.tabText(indx) if tlabel == 'Layer Editor': self.parent.layer.update_model() if tlabel == 'Profile Editor': self.parent.profile.update_model() if tlabel == 'Custom Profile Editor': self.parent.pview.update_model() # now do the calculations self.calc_field2(True, True) if tlabel == 'Profile Editor': self.parent.profile.update_plot() if tlabel == 'Custom Profile Editor': self.parent.pview.update_plot() def calc_field_grav_changes(self): """ calculates only grav changes """ self.lmod1 = self.parent.lmod1 self.lmod2 = self.parent.lmod2 self.lmod = self.lmod1 self.parent.profile.viewmagnetics = False self.parent.pview.viewmagnetics = False # Update the model from the view indx = self.parent.tabwidget.currentIndex() tlabel = self.parent.tabwidget.tabText(indx) if tlabel == 'Layer Editor': self.parent.layer.update_model() if tlabel == 'Profile Editor': self.parent.profile.update_model() if tlabel == 'Custom Profile Editor': self.parent.pview.update_model() # now do the calculations self.calc_field2(True) if tlabel == 'Profile Editor': self.parent.profile.update_plot() if tlabel == 'Custom Profile Editor': self.parent.pview.update_plot() def calc_field2(self, showreports=False, magcalc=False): """ Calculate magnetic and gravity field """ calc_field(self.lmod, pbars=self.pbars, showtext=self.showtext, parent=self.parent, showreports=showreports, magcalc=magcalc) def calc_regional(self): """ Calculates a gravity and magnetic regional value based on a single solid lithology model. This gets used in tab_param. The principle is that the maximum value for a solid model with fixed extents and depth, using the most COMMON lithology, would be the MAXIMUM AVERAGE value for any model which we would do. Therefore the regional is simply: REGIONAL = OBS GRAVITY MEAN - CALC GRAVITY MAX This routine calculates the last term. """ ltmp = list(self.lmod1.lith_list.keys()) ltmp.pop(ltmp.index('Background')) text, okay = QtWidgets.QInputDialog.getItem( self.parent, 'Regional Test', 'Please choose the lithology to use:', ltmp) if not okay: return lmod1 = self.lmod1 self.lmod2 = LithModel() self.lmod2.lith_list.clear() numlayers = lmod1.numz layerthickness = lmod1.d_z self.lmod2.update(lmod1.numx, lmod1.numy, numlayers, lmod1.xrange[0], lmod1.yrange[1], lmod1.zrange[1], lmod1.dxy, layerthickness, lmod1.mht, lmod1.ght) self.lmod2.lith_index = self.lmod1.lith_index.copy() self.lmod2.lith_index[self.lmod2.lith_index != -1] = 1 self.lmod2.lith_list['Background'] = GeoData( self.parent, lmod1.numx, lmod1.numy, self.lmod2.numz, lmod1.dxy, self.lmod2.d_z, lmod1.mht, lmod1.ght) self.lmod2.lith_list['Regional'] = GeoData( self.parent, lmod1.numx, lmod1.numy, self.lmod2.numz, lmod1.dxy, self.lmod2.d_z, lmod1.mht, lmod1.ght) lithn = self.lmod2.lith_list['Regional'] litho = self.lmod1.lith_list[text] lithn.hintn = litho.hintn lithn.finc = litho.finc lithn.fdec = litho.fdec lithn.zobsm = litho.zobsm lithn.susc = litho.susc lithn.mstrength = litho.mstrength lithn.qratio = litho.qratio lithn.minc = litho.minc lithn.mdec = litho.mdec lithn.density = litho.density lithn.bdensity = litho.bdensity lithn.zobsg = litho.zobsg lithn.lith_index = 1 self.lmod = self.lmod2 self.calc_field2(False, False) self.calc_field2(False, True) self.lmod = self.lmod1 def grd_to_lith(self, curgrid): """ Assign the DTM to the lithology model """ d_x = curgrid.xdim d_y = curgrid.ydim utlx = curgrid.tlx utly = curgrid.tly gcols = curgrid.cols grows = curgrid.rows gxmin = utlx gymax = utly ndata = np.zeros([self.lmod.numy, self.lmod.numx]) for i in range(self.lmod.numx): for j in range(self.lmod.numy): xcrd = self.lmod.xrange[0]+(i+.5)*self.lmod.dxy ycrd = self.lmod.yrange[1]-(j+.5)*self.lmod.dxy xcrd2 = int((xcrd-gxmin)/d_x) ycrd2 = int((gymax-ycrd)/d_y) if (ycrd2 >= 0 and xcrd2 >= 0 and ycrd2 < grows and xcrd2 < gcols): ndata[j, i] = curgrid.data.data[ycrd2, xcrd2] return ndata def test_pattern(self): """ Displays a test pattern of the data - an indication of the edge of model field decay. It gives an idea about how reliable the calculated field on the edge of the model is. """ self.lmod1 = self.parent.lmod1 self.lmod2 = self.parent.lmod2 self.lmod = self.lmod1 self.calc_regional() magtmp = self.lmod2.griddata['Calculated Magnetics'].data grvtmp = self.lmod2.griddata['Calculated Gravity'].data regplt = plt.figure() axes = plt.subplot(121) etmp = dat_extent(self.lmod2.griddata['Calculated Magnetics'], axes) plt.title('Magnetic Data') ims = plt.imshow(magtmp, extent=etmp) mmin = magtmp.mean()-2*magtmp.std() mmax = magtmp.mean()+2*magtmp.std() mint = (magtmp.std()*4)/10. if magtmp.ptp() > 0: csrange = np.arange(mmin, mmax, mint) cns = plt.contour(magtmp, levels=csrange, colors='b', extent=etmp) plt.clabel(cns, inline=1, fontsize=10) cbar = plt.colorbar(ims, orientation='horizontal') cbar.set_label('nT') axes = plt.subplot(122) etmp = dat_extent(self.lmod2.griddata['Calculated Gravity'], axes) plt.title('Gravity Data') ims = plt.imshow(grvtmp, extent=etmp) mmin = grvtmp.mean()-2*grvtmp.std() mmax = grvtmp.mean()+2*grvtmp.std() mint = (grvtmp.std()*4)/10. if grvtmp.ptp() > 0: csrange = np.arange(mmin, mmax, mint) cns = plt.contour(grvtmp, levels=csrange, colors='y', extent=etmp) plt.clabel(cns, inline=1, fontsize=10) cbar = plt.colorbar(ims, orientation='horizontal') cbar.set_label('mgal') regplt.show() def update_graph(self, grvval, magval, modind): """ Updates the graph """ indx = self.parent.tabwidget.currentIndex() tlabel = self.parent.tabwidget.tabText(indx) self.lmod.lith_index = modind.copy() self.lmod.griddata['Calculated Gravity'].data = grvval.T.copy() self.lmod.griddata['Calculated Magnetics'].data = magval.T.copy() if tlabel == 'Layer Editor': self.parent.layer.combo() if tlabel == 'Profile Editor': self.parent.profile.update_plot(slide=True)
class GravMag(): """ The GravMag class holds generic magnetic and gravity modelling routines. Routine that will calculate the final versions of the field. Other, related code is here as well, such as the inversion routines. """ def __init__(self, parent): self.parent = parent self.lmod2 = LithModel() self.lmod1 = parent.lmod1 self.lmod = self.lmod1 self.showtext = parent.showtext if hasattr(parent, 'pbars'): self.pbars = parent.pbars else: self.pbars = None self.oldlithindex = None self.mfname = self.parent.modelfilename self.tmpfiles = {} self.actionregionaltest = QtWidgets.QAction('Regional\nTest') self.actioncalculate = QtWidgets.QAction('Calculate\nGravity\n(All)') self.actioncalculate2 = QtWidgets.QAction( 'Calculate\nMagnetics\n(All)') self.actioncalculate3 = QtWidgets.QAction( 'Calculate\nGravity\n(Changes Only)') self.actioncalculate4 = QtWidgets.QAction( 'Calculate\nMagnetics\n(Changes Only)') self.setupui() def setupui(self): """ Set up UI. Returns ------- None. """ self.parent.toolbardock.addSeparator() self.parent.toolbardock.addAction(self.actionregionaltest) self.parent.toolbardock.addSeparator() self.parent.toolbardock.addAction(self.actioncalculate) self.parent.toolbardock.addAction(self.actioncalculate2) self.parent.toolbardock.addAction(self.actioncalculate3) self.parent.toolbardock.addAction(self.actioncalculate4) self.parent.toolbardock.addSeparator() self.actionregionaltest.triggered.connect(self.test_pattern) self.actioncalculate.triggered.connect(self.calc_field_grav) self.actioncalculate2.triggered.connect(self.calc_field_mag) self.actioncalculate3.triggered.connect(self.calc_field_grav_changes) self.actioncalculate4.triggered.connect(self.calc_field_mag_changes) self.actioncalculate3.setEnabled(False) self.actioncalculate4.setEnabled(False) def calc_field_mag(self): """ Pre field-calculation routine. Returns ------- None. """ self.lmod1 = self.parent.lmod1 self.lmod = self.lmod1 self.parent.profile.viewmagnetics = True self.lmod.lith_index_mag_old[:] = -1 # now do the calculations self.calc_field2(True, True) self.parent.profile.update_plot() self.actioncalculate4.setEnabled(True) def calc_field_grav(self): """ Pre field-calculation routine. Returns ------- None. """ # Update this self.lmod1 = self.parent.lmod1 self.lmod = self.lmod1 self.parent.profile.viewmagnetics = False self.lmod.lith_index_grv_old[:] = -1 # now do the calculations self.calc_field2(True) self.parent.profile.update_plot() self.actioncalculate3.setEnabled(True) def calc_field_mag_changes(self): """ Calculate only magnetic field changes. Returns ------- None. """ self.lmod1 = self.parent.lmod1 self.lmod = self.lmod1 self.parent.profile.viewmagnetics = True # now do the calculations self.calc_field2(True, True) self.parent.profile.update_plot() def calc_field_grav_changes(self): """ Calculate only gravity field changes. Returns ------- None. """ self.lmod1 = self.parent.lmod1 self.lmod = self.lmod1 self.parent.profile.viewmagnetics = False # now do the calculations self.calc_field2(True) self.parent.profile.update_plot() def calc_field2(self, showreports=False, magcalc=False): """ Calculate magnetic and gravity field. Parameters ---------- showreports : bool, optional Flag for showing reports. The default is False. magcalc : bool, optional Flac for choosing the magnetic calculation. The default is False. Returns ------- None. """ calc_field(self.lmod, pbars=self.pbars, showtext=self.showtext, parent=self.parent, showreports=showreports, magcalc=magcalc) def calc_regional(self): """ Calculate magnetic and gravity regional. Calculates a gravity and magnetic regional value based on a single solid lithology model. This gets used in tab_param. The principle is that the maximum value for a solid model with fixed extents and depth, using the most COMMON lithology, would be the MAXIMUM AVERAGE value for any model which we would do. Therefore the regional is simply: REGIONAL = OBS GRAVITY MEAN - CALC GRAVITY MAX This routine calculates the last term. Returns ------- None. """ ltmp = list(self.lmod1.lith_list.keys()) ltmp.pop(ltmp.index('Background')) text, okay = QtWidgets.QInputDialog.getItem( self.parent, 'Regional Test', 'Please choose the lithology to use:', ltmp) if not okay: return lmod1 = self.lmod1 self.lmod2 = LithModel() self.lmod2.lith_list.clear() numlayers = lmod1.numz layerthickness = lmod1.d_z self.lmod2.update(lmod1.numx, lmod1.numy, numlayers, lmod1.xrange[0], lmod1.yrange[1], lmod1.zrange[1], lmod1.dxy, layerthickness, lmod1.mht, lmod1.ght) self.lmod2.lith_index = self.lmod1.lith_index.copy() self.lmod2.lith_index[self.lmod2.lith_index != -1] = 1 self.lmod2.lith_list['Background'] = GeoData(self.parent, lmod1.numx, lmod1.numy, self.lmod2.numz, lmod1.dxy, self.lmod2.d_z, lmod1.mht, lmod1.ght) self.lmod2.lith_list['Regional'] = GeoData(self.parent, lmod1.numx, lmod1.numy, self.lmod2.numz, lmod1.dxy, self.lmod2.d_z, lmod1.mht, lmod1.ght) lithn = self.lmod2.lith_list['Regional'] litho = self.lmod1.lith_list[text] lithn.hintn = litho.hintn lithn.finc = litho.finc lithn.fdec = litho.fdec lithn.zobsm = litho.zobsm lithn.susc = litho.susc lithn.mstrength = litho.mstrength lithn.qratio = litho.qratio lithn.minc = litho.minc lithn.mdec = litho.mdec lithn.density = litho.density lithn.bdensity = litho.bdensity lithn.zobsg = litho.zobsg lithn.lith_index = 1 self.lmod = self.lmod2 self.calc_field2(False, False) self.calc_field2(False, True) self.lmod = self.lmod1 def test_pattern(self): """ Displays a test pattern of the data. This is an indication of the edge of model field decay. It gives an idea about how reliable the calculated field on the edge of the model is. Returns ------- None. """ self.lmod1 = self.parent.lmod1 self.lmod = self.lmod1 self.calc_regional() magtmp = self.lmod2.griddata['Calculated Magnetics'].data grvtmp = self.lmod2.griddata['Calculated Gravity'].data regplt = plt.figure() axes = plt.subplot(121) etmp = dat_extent(self.lmod2.griddata['Calculated Magnetics'], axes) plt.title('Magnetic Data') ims = plt.imshow(magtmp, extent=etmp) mmin = magtmp.mean() - 2 * magtmp.std() mmax = magtmp.mean() + 2 * magtmp.std() mint = (magtmp.std() * 4) / 10. if magtmp.ptp() > 0: csrange = np.arange(mmin, mmax, mint) # cns = plt.contour(magtmp, levels=csrange, colors='b', extent=etmp) plt.contour(magtmp, levels=csrange, colors='b', extent=etmp) # plt.clabel(cns, inline=1, fontsize=10) cbar = plt.colorbar(ims, orientation='horizontal') cbar.set_label('nT') axes = plt.subplot(122) etmp = dat_extent(self.lmod2.griddata['Calculated Gravity'], axes) plt.title('Gravity Data') ims = plt.imshow(grvtmp, extent=etmp) mmin = grvtmp.mean() - 2 * grvtmp.std() mmax = grvtmp.mean() + 2 * grvtmp.std() mint = (grvtmp.std() * 4) / 10. if grvtmp.ptp() > 0: csrange = np.arange(mmin, mmax, mint) plt.contour(grvtmp, levels=csrange, colors='y', extent=etmp) # cns = plt.contour(grvtmp, levels=csrange, colors='y', extent=etmp) # plt.clabel(cns, inline=1, fontsize=10) cbar = plt.colorbar(ims, orientation='horizontal') cbar.set_label('mGal') plt.tight_layout() plt.get_current_fig_manager().window.setWindowIcon( self.parent.windowIcon()) regplt.show() def update_graph(self, grvval, magval, modind): """ Update the graph. Parameters ---------- grvval : numpy array Array of gravity values. magval : numpy array Array of magnetic values. modind : numpy array Model indices. Returns ------- None. """ indx = self.parent.tabwidget.currentIndex() tlabel = self.parent.tabwidget.tabText(indx) self.lmod.lith_index = modind.copy() self.lmod.griddata['Calculated Gravity'].data = grvval.T.copy() self.lmod.griddata['Calculated Magnetics'].data = magval.T.copy() if tlabel == 'Layer Editor': self.parent.layer.combo() if tlabel == 'Profile Editor': self.parent.profile.update_plot(slide=True)
def quick_model(numx=50, numy=40, numz=5, dxy=100., d_z=100., tlx=0., tly=0., tlz=0., mht=100., ght=0., finc=-67, fdec=-17, inputliths=None, susc=None, dens=None, minc=None, mdec=None, mstrength=None, hintn=30000.): """ Quick model function. Parameters ---------- numx : int, optional Number of x elements. The default is 50. numy : int, optional Number of y elements. The default is 40. numz : TYPE, optional number of z elements (layers). The default is 5. dxy : float, optional Cell size in x and y direction. The default is 100.. d_z : float, optional Layer thickness. The default is 100.. tlx : float, optional Top left x coordinate. The default is 0.. tly : float, optional Top left y coordinate. The default is 0.. tlz : float, optional Top left z coordinate. The default is 0.. mht : float, optional Magnetic sensor height. The default is 100.. ght : float, optional Gravity sensor height. The default is 0.. finc : float, optional Magnetic field inclination (degrees). The default is -67. fdec : TYPE, optional Magnetic field declination (degrees). The default is -17. inputliths : list or None, optional List of input lithologies. The default is None. susc : list or None, optional List of susceptibilities. The default is None. dens : list or None, optional List of densities. The default is None. minc : list or None, optional List of remanent inclinations (degrees). The default is None. mdec : list or None, optional List of remanent declinations (degrees). The default is None. mstrength : list or None, optional List of remanent magnetisations (A/m). The default is None. hintn : float, optional Magnetic field strength (nT). The default is 30000. Returns ------- lmod : LithModel Output model. """ if inputliths is None: inputliths = ['Generic'] if susc is None: susc = [0.01] if dens is None: dens = [3.0] lmod = LithModel() lmod.update(numx, numy, numz, tlx, tly, tlz, dxy, d_z, mht, ght) lmod.lith_list['Background'] = GeoData(None, numx, numy, numz, dxy, d_z, mht, ght) lmod.lith_list['Background'].susc = 0 lmod.lith_list['Background'].density = 2.67 lmod.lith_list['Background'].finc = finc lmod.lith_list['Background'].fdec = fdec lmod.lith_list['Background'].minc = finc lmod.lith_list['Background'].mdec = fdec lmod.lith_list['Background'].hintn = hintn j = 0 if len(inputliths) == 1: clrtmp = np.array([0]) else: clrtmp = np.arange(len(inputliths)) / (len(inputliths) - 1) clrtmp = cm.jet(clrtmp)[:, :-1] clrtmp *= 255 clrtmp = clrtmp.astype(int) for i in inputliths: j += 1 lmod.mlut[j] = clrtmp[j - 1] lmod.lith_list[i] = GeoData(None, numx, numy, numz, dxy, d_z, mht, ght) lmod.lith_list[i].susc = susc[j - 1] lmod.lith_list[i].density = dens[j - 1] lmod.lith_list[i].lith_index = j lmod.lith_list[i].finc = finc lmod.lith_list[i].fdec = fdec lmod.lith_list[i].hintn = hintn if mstrength is not None: lmod.lith_list[i].minc = minc[j - 1] lmod.lith_list[i].mdec = mdec[j - 1] lmod.lith_list[i].mstrength = mstrength[j - 1] return lmod