#!/usr/bin/env python # -*- coding: utf-8 -*- """ Four-point sensitivities ======================== In this example, we illustrate how to visualize the sensitivities of four-point arrays. You can easily loop over the plotting command to create something like: https://www.youtube.com/watch?v=lt1qV-2d5Ps """ import numpy as np import matplotlib.pyplot as plt import pygimli as pg import pygimli.meshtools as mt from pygimli.physics import ert ############################################################################### # We start by creating a ERT data container with three four-point arrays. scheme = pg.DataContainerERT() # elec_pos,elec_alts=np.genfromtxt('electrode_altitudes.txt',unpack=True,skip_header=1,max_rows=14,usecols=(1,2)) # sensors=np.column_stack([elec_pos,elec_alts]) nelecs = 10 pos = np.zeros((nelecs, 2)) pos[:, 0] = np.linspace(5, 25, nelecs) scheme.setSensorPositions(pos) measurements = np.array(( [0, 3, 6, 9], # Dipole-Dipole [0, 9, 3, 6], # Wenner [0, 9, 4, 5] # Schlumberger )) for i, elec in enumerate("abmn"): scheme[elec] = measurements[:,i] scheme["k"] = ert.createGeometricFactors(scheme) ############################################################################### # Now we set up a 2D mesh. world = mt.createWorld(start=[0, 0], end=[30, -10], worldMarker=True, layers=[-2,-5]) for pos in scheme.sensorPositions(): world.createNode(pos) mesh = mt.createMesh(world, area=.05, quality=33, marker=1) # In[19]: ############################################################################### # As a last step we invoke the ERT manager and calculate the Jacobian for a # homogeneous half-space. #mesh.setCellMarkers(np.arange(0,mesh.cellCount(),1), 0) fop = ert.ERTModelling() fop.setData(scheme) fop.setMesh(mesh) fop.setRegionProperties('*', background=False) model = np.ones(mesh.cellCount()) invmesh=fop.paraDomain fop.createJacobian(model) # In[20]: ############################################################################### # Final visualization def getABMN(scheme, idx): """ Get coordinates of four-point cfg with id `idx` from DataContainerERT `scheme`.""" coords = {} for elec in "abmn": elec_id = int(scheme(elec)[idx]) elec_pos = scheme.sensorPosition(elec_id) coords[elec] = elec_pos.x(), elec_pos.y() return coords def plotABMN(ax, scheme, idx): """ Visualize four-point configuration on given axes. """ coords = getABMN(scheme, idx) for elec in coords: x, y = coords[elec] if elec in "ab": color = "red" else: color = "blue" ax.plot(x, y, marker=".", color=color, ms=10) ax.annotate(elec.upper(), xy=(x, y), ha="center", fontsize=10, bbox=dict( boxstyle="round", fc=(0.8, 0.8, 0.8), ec=color), xytext=(0, 20), textcoords='offset points', arrowprops=dict( arrowstyle="wedge, tail_width=.5", fc=color, ec=color, patchA=None, alpha=0.75)) ax.plot(coords["a"][0],) labels = ["Dipole-Dipole", "Wenner", "Schlumberger"] fig, ax = plt.subplots(scheme.size(), 1, sharex=True, figsize=(6,8)) for i, sens in enumerate(fop.jacobian()): # Label in lower-left corner ax[i].text(.01, .15, labels[i], horizontalalignment='left', verticalalignment='top', transform=ax[i].transAxes, fontsize=12, fontweight="bold") # Electrode annotations plotABMN(ax[i], scheme, i) # Log-scaled and normalized sensitivity normsens = pg.utils.logDropTol(sens/invmesh.cellSizes(), 8e-4) normsens /= np.max(normsens) pg.show(invmesh, normsens, cMap="RdGy_r", ax=ax[i], orientation="vertical", label="Normalized\nsensitivity", nLevs=3, cMin=-1, cMax=1) fig.tight_layout()