def createDefaultStartModel(self): """Create a meaningful starting model in case none is given.""" return pg.RVector(self.fop.regionManager().parameterCount(), 0.001) if __name__ == '__main__': # Set up FMM modelling operator and run a synthetic model mydata = pg.DataContainer('example_topo.sgt', 's g') print(mydata) mymesh = pg.meshtools.createParaMesh(mydata, boundary=0, paraBoundary=5, paraDepth=20, quality=34.5, paraMaxCellSize=5) mymesh.createNeighbourInfos() print(mymesh) slo = createGradientModel2D(mydata, mymesh, vTop=1000, vBot=2000) fwd = TravelTimeFMM(mymesh, mydata, frequency=500) # fwd.createRefinedForwardMesh(False) resp = fwd.response(slo) mydata.set('t', resp) print("ready with response, starting jacobian") fwd.createJacobian(slo) raise SystemExit # %% pg.plt.imshow(fwd.dataMatrix, interpolation='nearest') # %% one = pg.RVector(mydata.size(), 1.0) coverage = fwd.jacobian().transMult(one) pg.show(fwd.mesh(), coverage / fwd.mesh().cellSizes())
def invert(self, data=None, t=None, err=None, mesh=None, **kwargs): """Run actual inversion. Values for result/response are stored in the class members velocity/response Parameters ---------- useGradient : bool Create gradient for starting model from vtop to vbottom. vtop, vbottom : float starting (gradient) model velocities on top/at bottom of the mesh lam : float regularization parameter describing the strength of smoothness zWeight : float relative weight for purely vertical boundaries maxIter : int Maximum number of iterations startModel : array Slowness starting model for the inversion """ if 'verbose' in kwargs: self.setVerbose(kwargs.pop('verbose')) if data is not None: # setDataContainer would be better if t is not None: data.set('t', t) self.setDataContainer(data) if t is not None: self.dataContainer.set('t', t) if err is not None: self.error = err if mesh is not None: self.setMesh(mesh) if self.mesh is None: self.createMesh(**kwargs) startModel = kwargs.pop('startModel', None) self.pd = self.fop.regionManager().paraDomain() if startModel is None: useGradient = kwargs.pop('useGradient', True) if useGradient: startModel = createGradientModel2D( self.dataContainer, self.pd, kwargs.pop('vtop', 500.), kwargs.pop('vbottom', 5000.)) else: startModel = self.fop.createDefaultStartModel() if isinstance(startModel, (float, int)): startModel = pg.RVector(self.pd.cellCount(), startModel) self.fop.setStartModel(startModel) zWeight = kwargs.pop('zWeight', 0.2) if 'zweight' in kwargs: zWeight = kwargs.pop('zweight', 0.2) print("zweight option will be removed soon. " "Please use zWeight instead.") self.fop.regionManager().setZWeight(zWeight) self.inv.setData(self.dataContainer('t')) self.inv.setLambda(kwargs.pop('lam', 30.)) if 'threadCount' in kwargs: # just for backward compatibility self.fop.setThreadCount(kwargs.pop('threadCount')) if 'max_iter' in kwargs: # just for backward compatibility self.inv.setMaxIter(kwargs.pop('max_iter')) if 'maxIter' in kwargs: # the better way self.inv.setMaxIter(kwargs.pop('maxIter')) if 'robustData' in kwargs: self.inv.setRobustData(kwargs.pop('robustData')) if 'blockyModel' in kwargs: self.inv.setBlockyModel(kwargs.pop('blockyModel')) if kwargs.pop('referenceModel', False): self.inv.setReferenceModel(startModel) if not hasattr(self.error, '__iter__'): self.error = Refraction.estimateError( self.dataContainer, kwargs.pop('error', 0.003)) # abs err in s self.inv.setAbsoluteError(self.error) self.fop.jacobian().clear() slowness = self.inv.run() self.velocity = 1. / slowness self.response = self.inv.response() # use self.model() to access to this self.model = self.velocity return self.velocity
def invert(self, data=None, t=None, err=None, mesh=None, **kwargs): """Run actual inversion (first creating inversion object if not there) result/response is stored in the class attribute velocity/response Parameters ---------- vtop, vbottom : float starting (gradient) model velocities on top/at bottom of the mesh lam : float regularization parameter describing the strength of smoothness zweight : float relative weight for purely vertical boundaries """ if data is not None: # setDataContainer would be better if t is not None: data.set('t', t) self.setDataContainer(data) if t is not None: self.dataContainer.set('t', t) if err is not None: self.error = err if mesh is not None: self.setMesh(mesh) if self.mesh is None: self.createMesh(**kwargs) useGradient = kwargs.pop('useGradient', True) if useGradient: self.fop.setStartModel(createGradientModel2D( self.dataContainer, self.fop.regionManager().paraDomain(), kwargs.pop('vtop', 500.), kwargs.pop('vbottom', 5000.))) else: self.fop.setStartModel(self.fop.createDefaultStartModel()) self.fop.regionManager().setZWeight(kwargs.pop('zweight', 0.2)) self.inv.setData(self.dataContainer('t')) self.inv.setLambda(kwargs.pop('lam', 30.)) if 'max_iter' in kwargs: # just for backward compatibility self.inv.setMaxIter(kwargs.pop('max_iter')) if 'maxIter' in kwargs: # the better way self.inv.setMaxIter(kwargs.pop('maxIter')) if 'robustData' in kwargs: self.inv.setRobustData(kwargs.pop('robustData')) if 'blockyModel' in kwargs: self.inv.setBlockyModel(kwargs.pop('blockyModel')) if not hasattr(self.error, '__iter__'): self.error = Refraction.estimateError( self.dataContainer, kwargs.pop('error', 0.003)) # abs err in s self.inv.setAbsoluteError(self.error) self.fop.jacobian().clear() slowness = self.inv.run() self.velocity = 1. / slowness self.response = self.inv.response() self.model = self.velocity#(self.paraDomain.cellMarkers()) return self.velocity
dt = self.timeMatrix[iS] + self.timeMatrix[iG] - tsr weight = np.maximum(1 - 2 * self.frequency * dt, 0.0) # print(pg.sum(pg.sign(weight))) wa = weight * self.cellSizes self.jacobian()[i] = wa / np.sum(wa) * tsr / slowness if __name__ == '__main__': """ Set up FMM modelling operator and run a synthetic model """ data = pg.DataContainer('example_topo.sgt', 's g') print(data) mesh = pg.meshtools.createParaMesh(data, boundary=0, paraBoundary=5, paraDepth=20, quality=34.5, paraMaxCellSize=5) mesh.createNeighbourInfos() print(mesh) slo = createGradientModel2D(data, mesh, vTop=500, vBot=2500) fwd = TravelTimeFMM(mesh, data, frequency=500) resp = fwd.response(slo) pg.plt.imshow(fwd.dataMatrix, interpolation='nearest') fwd.createJacobian(slo) pg.plt.imshow(fwd.dataMatrix, interpolation='nearest') # %% if 0: pg.show(mesh, fwd.timeMatrix[21])
def invert(self, data=None, t=None, err=None, mesh=None, **kwargs): """Run actual inversion (first creating inversion object if not there) result/response is stored in the class attribute velocity/response Parameters ---------- vtop, vbottom : float starting (gradient) model velocities on top/at bottom of the mesh lam : float regularization parameter describing the strength of smoothness zWeight : float relative weight for purely vertical boundaries """ if 'verbose' in kwargs: self.setVerbose(kwargs.pop('verbose')) if data is not None: # setDataContainer would be better if t is not None: data.set('t', t) self.setDataContainer(data) if t is not None: self.dataContainer.set('t', t) if err is not None: self.error = err if mesh is not None: self.setMesh(mesh) if self.mesh is None: self.createMesh(**kwargs) useGradient = kwargs.pop('useGradient', True) if useGradient: self.fop.setStartModel( createGradientModel2D(self.dataContainer, self.fop.regionManager().paraDomain(), kwargs.pop('vtop', 500.), kwargs.pop('vbottom', 5000.))) else: self.fop.setStartModel(self.fop.createDefaultStartModel()) zWeight = kwargs.pop('zWeight', 0.2) if 'zweight' in kwargs: zWeight = kwargs.pop('zweight', 0.2) print("zweight option will be removed soon. " "Please use zWeight instead.") self.fop.regionManager().setZWeight(zWeight) self.inv.setData(self.dataContainer('t')) self.inv.setLambda(kwargs.pop('lam', 30.)) if 'max_iter' in kwargs: # just for backward compatibility self.inv.setMaxIter(kwargs.pop('max_iter')) if 'maxIter' in kwargs: # the better way self.inv.setMaxIter(kwargs.pop('maxIter')) if 'robustData' in kwargs: self.inv.setRobustData(kwargs.pop('robustData')) if 'blockyModel' in kwargs: self.inv.setBlockyModel(kwargs.pop('blockyModel')) if not hasattr(self.error, '__iter__'): self.error = Refraction.estimateError( self.dataContainer, kwargs.pop('error', 0.003)) # abs err in s self.inv.setAbsoluteError(self.error) self.fop.jacobian().clear() slowness = self.inv.run() self.velocity = 1. / slowness self.response = self.inv.response() # use self.model() to access to this self.model = self.velocity return self.velocity
# ERT inversion ert = ERTManager() ert.setMesh(meshERT) resinv = ert.invert(ertData, lam=30, zWeight=zWeight, maxIter=maxIter) print("ERT chi: %.2f" % ert.inv.chi2()) print("ERT rms: %.2f" % ert.inv.inv.relrms()) np.savetxt("res_conventional_%d.dat" % case, resinv) # Seismic inversion ttData = pg.DataContainer("tttrue.dat") print(ttData) rst = TravelTimeManager(verbose=True) rst.setMesh(meshRST, secNodes=3) veltrue = np.loadtxt("veltrue.dat") startmodel = createGradientModel2D(ttData, meshRST, np.min(veltrue), np.max(veltrue)) np.savetxt("rst_startmodel_%d.dat" % case, 1 / startmodel) vest = rst.invert(ttData, zWeight=zWeight, startModel=startmodel, maxIter=maxIter, lam=220) print("RST chi: %.2f" % rst.inv.chi2()) print("RST rms: %.2f" % rst.inv.inv.relrms()) rst.rayCoverage().save("rst_coverage_%d.dat" % case) np.savetxt("vel_conventional_%d.dat" % case, vest)
# TODO: check "invalid value in true divide" warning def createDefaultStartModel(self): """Create a meaningful starting model in case none is given.""" return pg.RVector(self.fop.regionManager().parameterCount(), 0.001) if __name__ == '__main__': # Set up FMM modelling operator and run a synthetic model mydata = pg.DataContainer('example_topo.sgt', 's g') print(mydata) mymesh = pg.meshtools.createParaMesh(mydata, boundary=0, paraBoundary=5, paraDepth=20, quality=34.5, paraMaxCellSize=5) mymesh.createNeighbourInfos() print(mymesh) slo = createGradientModel2D(mydata, mymesh, vTop=1000, vBot=2000) fwd = TravelTimeFMM(mymesh, mydata, frequency=500) # fwd.createRefinedForwardMesh(False) resp = fwd.response(slo) mydata.set('t', resp) print("ready with response, starting jacobian") fwd.createJacobian(slo) raise SystemExit # %% pg.plt.imshow(fwd.dataMatrix, interpolation='nearest') # %% one = pg.RVector(mydata.size(), 1.0) coverage = fwd.jacobian().transMult(one) pg.show(fwd.mesh(), coverage/fwd.mesh().cellSizes())
n_rst = ttData.size() n_ert = ertScheme.size() avg = (n_rst + n_ert) / 2 weight_rst = avg / n_rst weight_ert = avg / n_ert else: weight_rst = 1 weight_ert = 1 error = pg.cat( rst.relErrorVals(ttData) / weight_rst, ertScheme("err") / weight_ert) minvel = 1000 maxvel = 5000 velstart = 1 / createGradientModel2D(ttData, paraDomain, minvel, maxvel) rhostart = np.ones_like(velstart) * np.mean(ertScheme("rhoa")) fas, fis, fws, _ = fpm.all(rhostart, velstart) frs = np.ones_like(fas) - fpm.phi frs[frs <= fr_min] = fr_min + 0.01 frs[frs >= fr_max] = fr_max - 0.01 if fixcells is not False: fis[fixcells] = 0.0 startmodel = np.concatenate((fws, fis, fas, frs)) # Fix small values to avoid problems in first iteration startmodel[startmodel <= 0.001] = 0.001 inv = JointInv(JM, data, error, startmodel, frmin=fr_min, frmax=fr_max, lam=lam, maxIter=maxIter)