Field data inversion (“Koenigsee”)#

This minimalistic example shows how to use the Refraction Manager to invert a field data set. Here, we consider the Koenigsee data set, which represents classical refraction seismics data set with slightly heterogeneous overburden and some high-velocity bedrock. The data file can be found in the pyGIMLi example data repository.

# We import pyGIMLi and the traveltime module.

import pygimli as pg
import pygimli.physics.traveltime as tt

The helper function pg.getExampleData downloads the data set to a temporary location and loads it. Printing the data reveals that there are 714 data points using 63 sensors (shots and geophones) with the data columns s (shot), g (geophone), and t (traveltime). By default, there is also a validity flag.

data = pg.getExampleData("traveltime/koenigsee.sgt", verbose=True)
print(data)
[::::::::::::::::::::::::::::::::::::: 83% :::::::::::::::::::::::             ] 8193 of 9844 complete
[:::::::::::::::::::::::::::::::::::: 100% ::::::::::::::::::::::::::::::::::::] 9844 of 9844 complete
md5: 641890bb17cb2bdf052cbc348669dfd0
Data: Sensors: 63 data: 714, nonzero entries: ['g', 's', 't', 'valid']

Let’s have a look at the data in the form of traveltime curves.

fig, ax = pg.plt.subplots()
tt.drawFirstPicks(ax, data)
plot 04 koenigsee
[[<matplotlib.lines.Line2D object at 0x7fa06fdc51f0>], [<matplotlib.lines.Line2D object at 0x7fa074b67040>], [<matplotlib.lines.Line2D object at 0x7fa06fd0d2b0>], [<matplotlib.lines.Line2D object at 0x7fa06fd0d4c0>], [<matplotlib.lines.Line2D object at 0x7fa074bfb3d0>], [<matplotlib.lines.Line2D object at 0x7fa06fdb93d0>], [<matplotlib.lines.Line2D object at 0x7fa074942070>], [<matplotlib.lines.Line2D object at 0x7fa074c96a60>], [<matplotlib.lines.Line2D object at 0x7fa06feac730>], [<matplotlib.lines.Line2D object at 0x7fa06feacca0>], [<matplotlib.lines.Line2D object at 0x7fa0749b5790>], [<matplotlib.lines.Line2D object at 0x7fa074b73580>], [<matplotlib.lines.Line2D object at 0x7fa074b73b50>], [<matplotlib.lines.Line2D object at 0x7fa074b73220>], [<matplotlib.lines.Line2D object at 0x7fa03eb21c10>]]

We initialize the refraction manager.

mgr = tt.TravelTimeManager(data)

# Alternatively, one can plot a matrix plot of apparent velocities which is the
# more general function also making sense for crosshole data.

ax, cbar = mgr.showData()
plot 04 koenigsee

Finally, we call the invert method and plot the result.The mesh is created based on the sensor positions on-the-fly.

mgr.invert(secNodes=3, paraMaxCellSize=5.0,
           zWeight=0.2, vTop=500, vBottom=5000, verbose=1)
fop: <pygimli.physics.traveltime.modelling.TravelTimeDijkstraModelling object at 0x7fa06fe48040>
Data transformation: <pygimli.core._pygimli_.RTrans object at 0x7fa06fe48e00>
Model transformation (cumulative):
         0 <pygimli.core._pygimli_.RTransLogLU object at 0x7fa074eacb80>
min/max (data): 3.5e-04/0.03
min/max (error): 3%/3%
min/max (start model): 2.0e-04/0.002
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
inv.iter 1 ... chi² = 12.31 (dPhi = 91.5%) lam: 20
--------------------------------------------------------------------------------
inv.iter 2 ... chi² = 8.91 (dPhi = 27.39%) lam: 20.0
--------------------------------------------------------------------------------
inv.iter 3 ... chi² = 6.4 (dPhi = 27.51%) lam: 20.0
--------------------------------------------------------------------------------
inv.iter 4 ... chi² = 5.59 (dPhi = 12.03%) lam: 20.0
--------------------------------------------------------------------------------
inv.iter 5 ... chi² = 5.04 (dPhi = 9.46%) lam: 20.0
--------------------------------------------------------------------------------
inv.iter 6 ... chi² = 4.46 (dPhi = 10.61%) lam: 20.0
--------------------------------------------------------------------------------
inv.iter 7 ... chi² = 4.08 (dPhi = 7.91%) lam: 20.0
--------------------------------------------------------------------------------
inv.iter 8 ... chi² = 3.85 (dPhi = 5.12%) lam: 20.0
--------------------------------------------------------------------------------
inv.iter 9 ... chi² = 3.71 (dPhi = 3.25%) lam: 20.0
--------------------------------------------------------------------------------
inv.iter 10 ... chi² = 3.61 (dPhi = 2.01%) lam: 20.0
--------------------------------------------------------------------------------
inv.iter 11 ... chi² = 3.56 (dPhi = 1.33%) lam: 20.0
################################################################################
#                 Abort criteria reached: dPhi = 1.33 (< 2.0%)                 #
################################################################################

1090 [867.0666049979378,...,2677.8613792659903]

First have a look at the data fit. Plot the measured (crosses) and modelled (lines) traveltimes.

ax, cbar = mgr.showData(firstPicks=True, linewidth=0)
tt.drawFirstPicks(ax, data, mgr.inv.response, marker=None)
plot 04 koenigsee
[[<matplotlib.lines.Line2D object at 0x7fa074d64310>], [<matplotlib.lines.Line2D object at 0x7fa074d64a30>], [<matplotlib.lines.Line2D object at 0x7fa074d6f0a0>], [<matplotlib.lines.Line2D object at 0x7fa074d6f700>], [<matplotlib.lines.Line2D object at 0x7fa074d6fd60>], [<matplotlib.lines.Line2D object at 0x7fa074cfb400>], [<matplotlib.lines.Line2D object at 0x7fa074cfba60>], [<matplotlib.lines.Line2D object at 0x7fa074d07100>], [<matplotlib.lines.Line2D object at 0x7fa074d07760>], [<matplotlib.lines.Line2D object at 0x7fa074d07dc0>], [<matplotlib.lines.Line2D object at 0x7fa074d12460>], [<matplotlib.lines.Line2D object at 0x7fa074d12ac0>], [<matplotlib.lines.Line2D object at 0x7fa074d1f160>], [<matplotlib.lines.Line2D object at 0x7fa074d1f7c0>], [<matplotlib.lines.Line2D object at 0x7fa074d1fe20>]]

Show resulting tomogram along with fit. You may want to save your results.

mgr.showResultAndFit()
mgr.saveResult()  # saves the results (mesh, velocity, vtk) in a folder
plot 04 koenigsee
'./20230524-13.17/TravelTimeManager'

You can plot only the model and customize with a bunch of keywords

ax, cbar = mgr.showResult(logScale=False, cMin=500, cMax=3000, cMap="plasma_r",
                          coverage=mgr.standardizedCoverage())
mgr.drawRayPaths(ax=ax, color="k", lw=0.3, alpha=0.5)

# mgr.coverage() yields the ray coverage in m and standardizedCoverage as 0/1
plot 04 koenigsee
<matplotlib.collections.LineCollection object at 0x7fa029e8b100>

You can play around with the gradient starting model (vTop and vBottom arguments) and the regularization strength lam and customize the mesh.

Total running time of the script: ( 0 minutes 38.179 seconds)

Gallery generated by Sphinx-Gallery