def generate_forward_data(): """Generate synthetic forward data that we then invert""" scheme = get_scheme() mesh = get_fwd_mesh() rhomap = [ [1, pg.utils.complex.toComplex(100, 0 / 1000)], # Magnitude: 50 ohm m, Phase: -50 mrad [2, pg.utils.complex.toComplex(50, 0 / 1000)], [3, pg.utils.complex.toComplex(100, -50 / 1000)], ] rho = pg.solver.parseArgToArray(rhomap, mesh.cellCount(), mesh) fig, axes = plt.subplots(2, 1, figsize=(16 / 2.54, 16 / 2.54)) pg.show( mesh, data=np.log(np.abs(rho)), ax=axes[0], label=r"$log_{10}(|\rho|~[\Omega m])$" ) pg.show(mesh, data=np.abs(rho), ax=axes[1], label=r"$|\rho|~[\Omega m]$") pg.show( mesh, data=np.arctan2(np.imag(rho), np.real(rho)) * 1000, ax=axes[1], label=r"$\phi$ [mrad]", cMap='jet_r' ) data = ert.simulate( mesh, res=rhomap, scheme=scheme, # noiseAbs=0.0, # noiseLevel=0.0, ) r_complex = data['rhoa'].array() * np.exp(1j * data['phia'].array()) # Please note the apparent negative (resistivity) phases! fig, axes = plt.subplots(2, 2, figsize=(16 / 2.54, 16 / 2.54)) ert.showERTData(data, vals=data['rhoa'], ax=axes[0, 0]) # phia is stored in radians, but usually plotted in milliradians ert.showERTData( data, vals=data['phia'] * 1000, label=r'$\phi$ [mrad]', ax=axes[0, 1]) ert.showERTData( data, vals=np.real(r_complex), ax=axes[1, 0], label=r"$Z'$~[$\Omega$m" ) ert.showERTData( data, vals=np.imag(r_complex), ax=axes[1, 1], label=r"$Z''$~[$\Omega$]" ) fig.tight_layout() fig.show() return r_complex
def plot_inv_pars(filename, d, response, Wd, iteration='start'): """Plot error-weighted residuals""" fig, axes = plt.subplots(1, 2, figsize=(20 / 2.54, 10 / 2.54)) psi = Wd.dot(d - response) ert.showERTData( scheme, vals=psi.real, ax=axes[0], label=r"$(d' - f') / \epsilon$" ) ert.showERTData( scheme, vals=psi.imag, ax=axes[1], label=r"$(d'' - f'') / \epsilon$" ) fig.suptitle( 'Error weighted residuals of iteration {}'.format(iteration), y=1.00) fig.tight_layout()
rm.fillConstraints(Wm) Wm = pg.utils.sparseMatrix2coo(Wm) ############################################################################### # read-in data and determine error parameters filename = pg.getExampleFile( 'CR/synthetic_modeling/data_rre_rim.dat', load=False, verbose=True) data_rre_rim = np.loadtxt(filename) N = int(data_rre_rim.size / 2) d_rcomplex = data_rre_rim[:N] + 1j * data_rre_rim[N:] dmag = np.abs(d_rcomplex) dpha = np.arctan2(d_rcomplex.imag, d_rcomplex.real) * 1000 fig, axes = plt.subplots(1, 2, figsize=(20 / 2.54, 10 / 2.54)) k = np.array(ert.createGeometricFactors(scheme)) ert.showERTData( scheme, vals=dmag * k, ax=axes[0], label=r'$|\rho_a|~[\Omega$m]') ert.showERTData(scheme, vals=dpha, ax=axes[1], label=r'$\phi_a~[mrad]$') # real part: log-magnitude # imaginary part: phase [rad] d_rlog = np.log(d_rcomplex) # add some noise np.random.seed(42) noise_magnitude = np.random.normal( loc=0, scale=np.exp(d_rlog.real) * 0.04 ) # absolute phase error
def show(obj=None, data=None, **kwargs): """Mesh and model visualization. Syntactic sugar to show a obj with data. Forwards to a known visualization for obj. Typical is :py:mod:`pygimli.viewer.showMesh` or :py:mod:`pygimli.viewer.mayaview.showMesh3D` to show most of the typical 2D and 3D content. See tutorials and examples for usage hints. An empty show call creates an empty ax window. Parameters ---------- obj: obj obj can be so far. * :gimliapi:`GIMLI::Mesh` or list of meshes * DataContainer * pg.core.Sparse[Map]Matrix data: iterable Optionally data to visualize. See appropriate show function. Keyword Arguments ----------------- **kwargs Additional kwargs forward to appropriate show functions. * ax : axe [None] Matplotlib axes object. Create a new if necessary. * fitView : bool [True] Scale x and y limits to match the view. Returns ------- Return the results from the showMesh* functions. Usually the axe object and a colorbar. See Also -------- showMesh """ if "axes" in kwargs: print("Deprecation Warning: Please use keyword `ax` instead of `axes`") kwargs['ax'] = kwargs.pop('axes', None) if isinstance(obj, pg.DataContainerERT): from pygimli.physics.ert import showERTData return showERTData(obj, vals=kwargs.pop('vals', data), **kwargs) if isinstance(obj, pg.core.MatrixBase): ax, _ = pg.show() return drawMatrix(ax, obj, **kwargs) mesh = kwargs.pop('mesh', obj) if isinstance(mesh, list): ax = kwargs.pop('ax', None) fitView = kwargs.pop('fitView', ax is None) ax, cBar = show(mesh[0], data, hold=1, ax=ax, fitView=fitView, **kwargs) xMin = mesh[0].xMin() xMax = mesh[0].xMax() yMin = mesh[0].yMin() yMax = mesh[0].yMax() for m in mesh[1:]: ax, cBar = show(m, data, ax=ax, hold=1, fitView=False, **kwargs) xMin = min(xMin, m.xMin()) xMax = max(xMax, m.xMax()) yMin = min(yMin, m.yMin()) yMax = max(yMax, m.yMax()) # ax.relim() # ax.autoscale_view(tight=True) if fitView is not False: ax.set_xlim([xMin, xMax]) ax.set_ylim([yMin, yMax]) # print(ax.get_data_interval()) return ax, cBar if isinstance(mesh, pg.Mesh): if mesh.dim() == 2: if pg.zero(pg.y(mesh)): pg.info("swap z<->y coordinates for visualization.") meshSwap = pg.Mesh(mesh) for n in meshSwap.nodes(): n.pos()[1] = n.pos()[2] return showMesh(meshSwap, data, **kwargs) return showMesh(mesh, data, **kwargs) elif mesh.dim() == 3: from .vistaview import showMesh3D return showMesh3D(mesh, data, **kwargs) else: pg.error("ERROR: Mesh not valid.", mesh) ax = kwargs.pop('ax', None) if ax is None: ax = plt.subplots()[1] return ax, None
def show(obj=None, data=None, **kwargs): """Mesh and model visualization. Syntactic sugar to show a obj with data. Forwards to a known visualization for obj. Typical is :py:mod:`pygimli.viewer.showMesh` or :py:mod:`pygimli.viewer.mayaview.showMesh3D` to show most of the typical 2D and 3D content. See tutorials and examples for usage hints. An empty show call creates an empty ax window. Parameters ---------- obj: obj obj can be so far. * :gimliapi:`GIMLI::Mesh` or list of meshes * DataContainer * pg.core.Sparse[Map]Matrix data: iterable Optionally data to visualize. See appropriate show function. Keyword Arguments ----------------- **kwargs Additional kwargs forward to appropriate show functions. * ax : axe [None] Matplotlib axes object. Create a new if necessary. * fitView : bool [True] Scale x and y limits to match the view. Returns ------- Return the results from the showMesh* functions. Usually the axe object and a colorbar. See Also -------- showMesh """ if "axes" in kwargs: # remove me in 1.2 #20200515 print("Deprecation Warning: Please use keyword `ax` instead of `axes`") kwargs['ax'] = kwargs.pop('axes', None) ### Empty call just to create a axes if obj is None and not 'mesh' in kwargs.keys(): ax = kwargs.pop('ax', None) if ax is None: ax = plt.subplots(figsize=kwargs.pop('figsize', None))[1] return ax, None ### try to interprete obj containes a mesh if hasattr(obj, 'mesh'): return pg.show(obj.mesh, obj, **kwargs) ### try to interprete obj as ERT Data if isinstance(obj, pg.DataContainerERT): from pygimli.physics.ert import showERTData return showERTData(obj, vals=kwargs.pop('vals', data), **kwargs) ### try to interprete obj as matrices if isinstance(obj, pg.core.MatrixBase) or \ (isinstance(obj, np.ndarray) and obj.ndim == 2): return showMatrix(obj, **kwargs) try: from scipy.sparse import spmatrix if isinstance(obj, spmatrix): return showMatrix(obj, **kwargs) except ImportError: pass ### try to interprete obj as mesh or list of meshes mesh = kwargs.pop('mesh', obj) fitView = kwargs.get('fitView', True) if isinstance(mesh, list): ax = kwargs.pop('ax', None) ax, cBar = show(mesh[0], data, hold=1, ax=ax, fitView=fitView, **kwargs) for m in mesh[1:]: ax, cBar = show(m, data, ax=ax, hold=1, fitView=False, **kwargs) if fitView is not False: ax.autoscale(enable=True, axis='both', tight=True) ax.set_aspect('equal') return ax, cBar if isinstance(mesh, pg.Mesh): if mesh.dim() == 2: if pg.zero(pg.y(mesh)): pg.info("swap z<->y coordinates for visualization.") meshSwap = pg.Mesh(mesh) for n in meshSwap.nodes(): n.pos()[1] = n.pos()[2] return showMesh(meshSwap, data, **kwargs) return showMesh(mesh, data, **kwargs) elif mesh.dim() == 3: from .vistaview import showMesh3D return showMesh3D(mesh, data, **kwargs) else: pg.error("ERROR: Mesh not valid.", mesh) pg.error("Can't interprete obj: {0} to show.".format(obj)) return None, None
data = ert.simulate( mesh, res=rhomap, scheme=scheme, # noiseAbs=0.0, # noiseLevel=0.0, ) ############################################################################### # Visualize the modeled data # Convert magnitude and phase into a complex apparent resistivity rho_a_complex = data['rhoa'].array() * np.exp(1j * data['phia'].array()) # Please note the apparent negative (resistivity) phases! fig, axes = plt.subplots(2, 2, figsize=(16 / 2.54, 16 / 2.54)) ert.showERTData(data, vals=data['rhoa'], ax=axes[0, 0]) # phia is stored in radians, but usually plotted in milliradians ert.showERTData(data, vals=data['phia'] * 1000, label=r'$\phi$ [mrad]', ax=axes[0, 1]) ert.showERTData(data, vals=np.real(rho_a_complex), ax=axes[1, 0], label=r"$\rho_a'$~[$\Omega$m]") ert.showERTData(data, vals=np.imag(rho_a_complex), ax=axes[1, 1], label=r"$\rho_a''$~[$\Omega$m]") fig.tight_layout()