def jacobian4PM(meshERT, meshRST, schemeERT, schemeSRT, Fx, df=0.01, errorERT=0.03, errorSRT=0.0005): """Jacobian matrices by brute force.""" dataERT, dataSRT = forward4PM(meshERT, meshRST, schemeERT, schemeSRT, Fx) npar = np.prod(Fsyn.shape) jacERT = np.zeros((dataERT.size(), npar)) jacSRT = np.zeros((dataSRT.size(), npar)) for i in range(npar): print("\n") pg.boxprint("%d / %d" % (i + 1, npar)) print(Fx.flat[i], end=" ") Fx1 = np.copy(Fx) Fx1.flat[i] += df dataERT1, dataSRT1 = forward4PM(meshERT, meshRST, schemeERT, schemeSRT, Fx1) jacERT[:, i] = (np.log(dataERT1('rhoa')) - np.log(dataERT('rhoa'))) / df / errorERT jacSRT[:, i] = (dataSRT1('t') - dataSRT('t')) / df / errorSRT print("ready.") return jacERT, jacSRT
def run(self, dataVals, errorVals, **kwargs): """Run inversion. The inversion will always start from the starting model taken from the forward operator. If you want to run the inversion from a specified prior model, e.g., from a other run, set this model as starting model to the FOP (fop.setStartModel). Any self.inv.setModel() settings will be overwritten. Parameters ---------- dataVals : iterable Data values errorVals : iterable Relative error values. dv / v Keyword Arguments ----------------- maxIter : int Overwrite class settings for maximal iterations number. dPhi : float [1] Overwrite class settings for delta data phi aborting criteria. Default is 1% """ self.reset() if self.isFrameWork: pg.critical('in use?') return self._inv.run(dataVals, errorVals, **kwargs) if self.fop is None: raise Exception( "Need a valid forward operator for the inversion run.") maxIter = kwargs.pop('maxIter', self.maxIter) minDPhi = kwargs.pop('dPhi', self.minDPhi) self.verbose = kwargs.pop('verbose', self.verbose) self.debug = kwargs.pop('debug', self.debug) self.robustData = kwargs.pop('robustData', False) lam = kwargs.pop('lam', 20) progress = kwargs.pop('progress', None) showProgress = kwargs.pop('showProgress', False) self.inv.setTransModel(self.fop.modelTrans) self.dataVals = dataVals self.errorVals = errorVals sm = kwargs.pop('startModel', None) if sm is not None: self.startModel = sm self.inv.setData(self._dataVals) self.inv.setRelativeError(self._errorVals) self.inv.setLambda(lam) # temporary set max iter to one for the initial run call maxIterTmp = self.maxIter self.maxIter = 1 if self.verbose: pg.info('Starting inversion.') print("fop:", self.inv.fop()) if isinstance(self.dataTrans, pg.trans.TransCumulative): print("Data transformation (cumulative):") for i in range(self.dataTrans.size()): print("\t", i, self.dataTrans.at(i)) else: print("Data transformation:", self.dataTrans) if isinstance(self.modelTrans, pg.trans.TransCumulative): print("Model transformation (cumulative):") for i in range(self.modelTrans.size()): if i < 10: print("\t", i, self.modelTrans.at(i)) else: print(".", end='') else: print("Model transformation:", self.modelTrans) print("min/max (data): {0}/{1}".format(pf(min(self._dataVals)), pf(max(self._dataVals)))) print("min/max (error): {0}%/{1}%".format( pf(100 * min(self._errorVals)), pf(100 * max(self._errorVals)))) print("min/max (start model): {0}/{1}".format( pf(min(self.startModel)), pf(max(self.startModel)))) ### To ensure reproduceability of the run() call inv.start() will ### reset self.inv.model() to fop.startModel(). self.fop.setStartModel(self.startModel) self.inv.setReferenceModel(self.startModel) if self.verbose: print("-" * 80) if self._preStep and callable(self._preStep): self._preStep(0, self) self.inv.start() self.maxIter = maxIterTmp if self._postStep and callable(self._postStep): self._postStep(0, self) if showProgress: self.showProgress(showProgress) lastPhi = self.phi() self.chi2History = [self.chi2()] self.modelHistory = [self.startModel] for i in range(1, maxIter): if self._preStep and callable(self._preStep): self._preStep(i, self) if self.verbose: print("-" * 80) print("inv.iter", i + 1, "... ", end='') try: self.inv.oneStep() except RuntimeError as e: print(e) pg.error('One step failed. ' 'Aborting and going back to last model') if np.isnan(self.model).any(): print(model) pg.critical('invalid model') resp = self.inv.response() chi2 = self.inv.chi2() self.chi2History.append(chi2) self.modelHistory.append(self.model) if showProgress: self.showProgress(showProgress) if self._postStep and callable(self._postStep): self._postStep(i, self) ### we need to check the following before oder after chi2 calc?? self.inv.setLambda(self.inv.getLambda() * self.inv.lambdaFactor()) if self.robustData: self.inv.robustWeighting() if self.inv.blockyModel(): self.inv.constrainBlocky() phi = self.phi() dPhi = phi / lastPhi if self.verbose: print("chi² = {0} (dPhi = {1}%) lam: {2}".format( round(chi2, 2), round((1 - dPhi) * 100, 2), self.inv.getLambda())) if chi2 <= 1 and self.stopAtChi1: print("\n") if self.verbose: pg.boxprint("Abort criterion reached: chi² <= 1 (%.2f)" % chi2) break if (dPhi > (1.0 - minDPhi / 100.0)) and i > 2: # if dPhi < -minDPhi: if self.verbose: pg.boxprint( "Abort criteria reached: dPhi = {0} (< {1}%)".format( round((1 - dPhi) * 100, 2), minDPhi)) break lastPhi = phi ### will never work as expected until we unpack kwargs .. any idea for # better strategy? # if len(kwargs.keys()) > 0: # print("Warning! unused keyword arguments", kwargs) self.model = self.inv.model() return self.model
def test(target=None, show=False, onlydoctests=False, coverage=False, htmlreport=False, abort=False, verbose=True): """Run docstring examples and additional tests. Examples -------- >>> import pygimli as pg >>> # You can test everything with pg.test() or test a single function: >>> pg.test("pg.utils.boxprint", verbose=False) >>> # The target argument can also be the function directly >>> from pygimli.utils import boxprint >>> pg.test(boxprint, verbose=False) Parameters ---------- target : function or string, optional Function or method to test. By default everything is tested. show : boolean, optional Show matplotlib windows during test run. They will be closed automatically. onlydoctests : boolean, optional Run test files in ../tests as well. coverage : boolean, optional Create a coverage report. Requires the pytest-cov plugin. htmlreport : str, optional Filename for HTML report such as www.pygimli.org/build_tests.html. Requires pytest-html plugin. abort : boolean, optional Return correct exit code, e.g. abort documentation build when a test fails. """ # Remove figure warnings plt.rcParams["figure.max_open_warning"] = 1000 printopt = np.get_printoptions() if verbose: pg.boxprint("Testing pygimli %s" % pg.__version__, sym="+") # Numpy compatibility (array string representation has changed) if np.__version__[:4] in ("1.14", "1.15"): np.set_printoptions(legacy="1.13") old_backend = plt.get_backend() if not show: plt.switch_backend("Agg") else: plt.ion() if target: if isinstance(target, str): # If target is a string, such as "pg.solver.solve" # the code below will overwrite target with the corresponding # imported function, so that doctest works. target = target.replace("pg.", "pygimli.") import importlib mod_name, func_name = target.rsplit('.', 1) mod = importlib.import_module(mod_name) target = getattr(mod, func_name) import doctest doctest.run_docstring_examples(target, globals(), verbose=verbose, optionflags=doctest.ELLIPSIS, name=target.__name__) return try: import pytest except ImportError: raise ImportError("pytest is required to run test suite. " "Try 'sudo pip install pytest'.") cwd = join(realpath(__path__[0]), '..') excluded = [ "gui", "physics/traveltime/example.py", "physics/em/fdemexample.py" ] if onlydoctests: excluded.append("testing") cmd = ([ "-v", "-rsxX", "--color", "yes", "--doctest-modules", "--durations", "5", cwd ]) for directory in excluded: cmd.extend(["--ignore", join(cwd, directory)]) if coverage: pc = pg.optImport("pytest_cov", "create a code coverage report") if pc: cmd.extend(["--cov", "pygimli"]) cmd.extend(["--cov-report", "term"]) if htmlreport: ph = pg.optImport("pytest_html", "create a html report") if ph: cmd.extend(["--html", htmlreport]) plt.close("all") exitcode = pytest.main(cmd) if abort: print("Exiting with exitcode", exitcode) sys.exit(exitcode) plt.switch_backend(old_backend) np.set_printoptions(**printopt)
import sys import numpy as np import pygimli as pg from fpinv import FourPhaseModel mesh = pg.load("mesh.bms") if len(sys.argv) > 1: pd = pg.load("paraDomain_2.bms") resinv = np.loadtxt("res_conventional_2.dat") vest = np.loadtxt("vel_conventional_2.dat") scenario = "Fig2" pg.boxprint(scenario) phi = 0.3 # Porosity assumed to calculate fi, fa, fw with 4PM else: pd = pg.load("paraDomain_1.bms") resinv = np.loadtxt("res_conventional_1.dat") vest = np.loadtxt("vel_conventional_1.dat") scenario = "Fig1" pg.boxprint(scenario) frtrue = np.load("true_model.npz")["fr"] phi = [] for cell in pd.cells(): idx = mesh.findCell(cell.center()).id() phi.append(1 - frtrue[idx]) phi = np.array(phi) # Save some stuff fpm = FourPhaseModel(phi=phi) fae, fie, fwe, maske = fpm.all(resinv, vest)
import numpy as np # for doc rendering on headless machines (jenkins server) import matplotlib matplotlib.use("Agg") import pkg_resources import sphinx import pygimli from sidebar_gallery import make_gallery try: # from _build.doc.conf_environment import * from conf_environment import * pygimli.boxprint("Building documentation out-of-source. Good.") print("DOXY_BUILD_DIR", DOXY_BUILD_DIR) except ImportError: TRUNK_PATH = '..' SPHINXDOC_PATH = '.' DOC_BUILD_DIR = '' DOXY_BUILD_DIR = '' pygimli.boxprint( "Building documentation in-source. Don't forget to make clean.") sys.path.append(os.path.abspath(SPHINXDOC_PATH)) sys.path.append(os.path.abspath(join(SPHINXDOC_PATH, '_sphinx-ext'))) # The following line is necessary for the Tools section sys.path.append(os.path.abspath(join(TRUNK_PATH, 'pygimli')))
elif i == 3: # ice lims = {"cMin": 0.01, "cMax": 0.5} elif i == 4: # air lims = {"cMin": 0.05, "cMax": 0.6} elif i == 5: # rock lims = {"cMin": 0.2, "cMax": 0.9} else: lims = lim(list(data[0][cov > 0]) + list(data[1][cov > 0])) logScale = True if "rho" in label else False ims = [] for j, ax in enumerate(row): if data[j] is None: ims.append(None) continue coverage = cov2 if j == 2 else cov pg.boxprint(j) print(meshs[j], len(coverage), len(data[j])) #color = "k" if j is 0 and i not in (1, 3, 5) else "w" ims.append( draw(ax, meshs[j], data[j], **lims, logScale=logScale, coverage=coverage)) ax.text(0.987, 0.05, minmax(data[j][coverage > 0]), transform=ax.transAxes, fontsize=fs, ha="right",
import numpy as np import pybert as pb import pygimli as pg import pygimli.meshtools as mt from pybert.manager import ERTManager from pygimli.physics import Refraction from pygimli.physics.traveltime import createRAData mesh = pg.load("mesh.bms") sensors = np.load("sensors.npy", allow_pickle=True) rhotrue = np.loadtxt("rhotrue.dat") veltrue = np.loadtxt("veltrue.dat") pg.boxprint("Simulate apparent resistivities") # Create more realistic data set ertScheme = pb.createData(sensors, "dd", spacings=[1, 2, 4]) k = pb.geometricFactors(ertScheme) ertScheme.markInvalid(pg.abs(k) > 5000) ertScheme.removeInvalid() ert = ERTManager() # Create suitable mesh for ert forward calculation # NOTE: In the published results paraMaxCellSize=1.0 was used, which is # increased here to allow testing on Continuous Integration services. meshERTFWD = mt.createParaMesh(ertScheme, quality=33.5, paraMaxCellSize=2.0,
# Fix small values to avoid problems in first iteration startmodel[startmodel <= 0.01] = 0.01 inv = JointInv(JM, data, error, startmodel, lam=lam, frmin=fr_min, frmax=fr_max, maxIter=maxIter) inv.setModel(startmodel) # Run inversion model = inv.run() pg.boxprint(("Chi squared fit:", inv.getChi2()), sym="+") # Save results fwe, fie, fae, fre = JM.fractions(model) fsum = fwe + fie + fae + fre print("Min/Max sum:", min(fsum), max(fsum)) rhoest = JM.fpm.rho(fwe, fie, fae, fre) velest = 1. / JM.fpm.slowness(fwe, fie, fae, fre) array_mask = np.array(((fae < 0) | (fae > 1 - fre)) | ((fie < 0) | (fie > 1 - fre)) | ((fwe < 0) | (fwe > 1 - fre)) | ((fre < 0) | (fre > 1)) | (fsum > 1.01))
def test(target=None, show=False, onlydoctests=False, coverage=False, htmlreport=False, abort=False, verbose=True): """Run docstring examples and additional tests. Examples -------- >>> import pygimli as pg >>> # You can test everything with pg.test() or test a single function: >>> pg.test("pg.utils.boxprint", verbose=False) >>> # The target argument can also be the function directly >>> from pygimli.utils import boxprint >>> pg.test(boxprint, verbose=False) Parameters ---------- target : function or string, optional Function or method to test. By default everything is tested. show : boolean, optional Show matplotlib windows during test run. They will be closed automatically. onlydoctests : boolean, optional Run test files in ../tests as well. coverage : boolean, optional Create a coverage report. Requires the pytest-cov plugin. htmlreport : str, optional Filename for HTML report such as www.pygimli.org/build_tests.html. Requires pytest-html plugin. abort : boolean, optional Return correct exit code, e.g. abort documentation build when a test fails. """ # Remove figure warnings plt.rcParams["figure.max_open_warning"] = 1000 printopt = np.get_printoptions() if verbose: pg.boxprint("Testing pygimli %s" % pg.__version__, sym="+") # Numpy compatibility (array string representation has changed) if np.__version__[:4] == "1.14": pg.warn("Some doctests will fail due to old numpy version.", "Consider upgrading to numpy >= 1.15") if target: if isinstance(target, str): # If target is a string, such as "pg.solver.solve" # the code below will overwrite target with the corresponding # imported function, so that doctest works. target = target.replace("pg.", "pygimli.") import importlib mod_name, func_name = target.rsplit('.', 1) mod = importlib.import_module(mod_name) target = getattr(mod, func_name) if show: # Keep figure openend if single function is tested plt.ioff() import doctest doctest.run_docstring_examples(target, globals(), verbose=verbose, optionflags=doctest.ELLIPSIS, name=target.__name__) return try: import pytest except ImportError: raise ImportError("pytest is required to run test suite. " "Try 'sudo pip install pytest'.") old_backend = plt.get_backend() if not show: plt.switch_backend("Agg") else: plt.ion() cwd = join(realpath(__path__[0]), '..') excluded = [ "gui", "physics/traveltime/example.py", "physics/em/fdemexample.py" ] if onlydoctests: excluded.append("testing") cmd = ([ "-v", "-rsxX", "--color", "yes", "--doctest-modules", "--durations", "5", cwd ]) for directory in excluded: cmd.extend(["--ignore", join(cwd, directory)]) if coverage: pc = pg.optImport("pytest_cov", "create a code coverage report") if pc: cmd.extend(["--cov", "pygimli"]) cmd.extend(["--cov-report", "term"]) if htmlreport: ph = pg.optImport("pytest_html", "create a html report") if ph: cmd.extend(["--html", htmlreport]) plt.close("all") exitcode = pytest.main(cmd) if abort: print("Exiting with exitcode", exitcode) sys.exit(exitcode) plt.switch_backend(old_backend) np.set_printoptions(**printopt)
tdirect = np.abs(x) / a # direct wave tmp = 1 + ((b**2 * np.abs(x)**2) / (2 * a**2)) trefrac = np.abs(b**-1 * np.arccosh(tmp)) return np.minimum(tdirect, trefrac) ############################################################################### # The loop below calculates the traveltimes and makes the comparison plot. fig, ax = plt.subplots(3, 2, figsize=(10, 10), sharex=True) for j, (case, mesh, vel) in enumerate( zip(["layered", "gradient"], [mesh_layered, mesh_gradient], [vel_layered, vel_gradient])): pg.boxprint(case) if case is "gradient": ana = analyticalSolutionGradient elif case is "layered": ana = analyticalSolution2Layer for boundary in mesh.boundaries(): boundary.setMarker(0) xmin, xmax = mesh.xmin(), mesh.xmax() mesh.createNeighbourInfos() # In order to use the Dijkstra, we extract the surface positions >0 mx = pg.x(mesh.positions()) my = pg.y(mesh.positions()) fi = pg.find((my == 0.0)) px = np.sort(mx(fi))