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
示例#2
0
    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
示例#3
0
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)
示例#4
0
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)
示例#5
0
文件: conf.py 项目: rf1991/gimli
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')))
示例#6
0
 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))
示例#9
0
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))