def plot_data_inversion(self, ii, pred, fixed=False):
     titles = ["Observed", "Predicted", "Normalized misfit"]
     x = np.arange(10) + 1
     y = np.arange(10) + 1
     xy = utils.ndgrid(x, y)
     fig, axs = plt.subplots(1, 3, figsize=(10, 3))
     if fixed:
         clim = (self.dobs.min(), self.dobs.max())
     else:
         clim = None
     out = utils.plot2Ddata(xy, self.dobs, ax=axs[0], clim=clim)
     plt.colorbar(out[0], ax=axs[0], fraction=0.02)
     out = utils.plot2Ddata(xy, pred[ii], ax=axs[1], clim=clim)
     plt.colorbar(out[0], ax=axs[1], fraction=0.02)
     out = utils.plot2Ddata(xy, (pred[ii] - self.dobs) / self.uncertainty,
                            ax=axs[2],
                            clim=(-3, 3))
     plt.colorbar(out[0], ax=axs[2], fraction=0.02, ticks=[-2, -1, 0, 1, 2])
     for ii, ax in enumerate(axs):
         ax.set_aspect(1)
         ax.set_title(titles[ii])
         ax.set_xlabel("Rx")
         ax.set_ylabel("Tx")
     plt.tight_layout()
     plt.show()
Exemple #2
0
    def plot_magnetic_flux(self, itime):
        bxy, xy = self.getSlices(
            self.mesh, self.B, itime, normal="Z", loc=-100.5, isz=True
        )
        bxz, xz = self.getSlices(self.mesh, self.B, itime, normal="Y", loc=0.0)
        label = "Magnetic flux density (T)"
        plt.figure(figsize=(12, 5))
        ax1 = plt.subplot(121)
        ax2 = plt.subplot(122)

        out_xy = utils.plot2Ddata(
            xy, bxy, vec=False, ncontour=300, contourOpts={"cmap": "viridis"}, ax=ax1
        )
        vmin_xy, vmax_xy = out_xy[0].get_clim()
        out_xz = utils.plot2Ddata(
            xz, bxz, vec=True, ncontour=300, contourOpts={"cmap": "viridis"}, ax=ax2
        )
        vmin_xz, vmax_xz = out_xz[0].get_clim()
        ax1.set_aspect("equal", adjustable="box")
        ax2.set_aspect("equal", adjustable="box")

        plt.colorbar(
            out_xy[0],
            ax=ax1,
            format="%.1e",
            ticks=np.linspace(vmin_xy, vmax_xy, 5),
            fraction=0.02,
        )
        cb = plt.colorbar(
            out_xz[0],
            ax=ax2,
            format="%.1e",
            ticks=np.linspace(vmin_xz, vmax_xz, 5),
            fraction=0.02,
        )
        cb.set_label(label)
        ax1.set_title("")
        ax1.set_xlabel("X (m)")
        ax1.set_ylabel("Y (m)")
        ax2.set_xlabel("X (m)")
        ax2.set_ylabel("Z (m)")
        ax1.set_xlim(self.xmin, self.xmax)
        ax1.set_ylim(self.ymin, self.ymax)
        ax2.set_xlim(self.xmin, self.xmax)
        ax2.set_ylim(self.zmin, self.zmax)
        ax1.plot(ax1.get_xlim(), np.zeros(2), "k--", lw=1)
        ax2.plot(ax1.get_xlim(), np.zeros(2) - 100.0, "k--", lw=1)
        ax2.plot(ax2.get_xlim(), np.zeros(2), "k-", lw=1)
        ax2.plot(0, 30, "ro", ms=5)
        title = ("Time at %.2f ms") % ((self.times[itime]) * 1e3)
        ax1.set_title(title)
        plt.tight_layout()
Exemple #3
0
def plot_gravity(survey, data, ax=None, axlabels=True, colorbar=True,
                 ncontour=10, contour_opts={}):
    """
    Shows a 2-D overhead map of a gravity survey
    :param survey: survey instance
    :param data: measurements
    :param ax: optional matplotlib.axes.Axes instance (into subplot);
        if None, create new set of axes and hit matplotlib.show() at the end
    :return: nothing (yet)
    """
    contourOpts = { 'cmap': 'bwr' }
    contourOpts.update(contour_opts)
    show = (ax is None)
    if show:
        fig = plt.figure(figsize=(6, 5))
        ax = plt.gca()
    locations = survey.receiver_locations
    quadcont, axsub = plot2Ddata(
        survey.receiver_locations, data, ax=ax,
        ncontour=ncontour, contourOpts=contourOpts
    )
    if axlabels:
        ax.set_title("Gravity Anomaly (Z-component)")
        ax.set_xlabel("x (m)")
        ax.set_ylabel("y (m)")
        colorbar_label = "Anomaly (mgal)"
    else:
        colorbar_label = ""
    if colorbar:
        plt.colorbar(quadcont, format="%.0g", pad=0.03, label=colorbar_label)
    if show:
        plt.show()
Exemple #4
0
def show_fdem_mag_map(fig, receiver_locations, mag_data):
    """

    Parameters
    ----------
    fig : matplotlib.figure.Figure
        Empty figure.
    receiver_locations : numpy.ndarray, shape(N*3)
        See fdem_forward_simulation.fdem_forward_simulation receiver_locations.
    mag_data : numpy.ndarray, shape(N*1)
        See fdem_forward_simulation.fdem_forward_simulation mag_data.

    Returns
    -------
    None.
    """

    fig.clf()

    mag_data_plotting = np.reshape(mag_data, (1, len(mag_data)))
    v_max = np.max(mag_data_plotting)
    v_min = np.min(mag_data_plotting)

    ax1 = fig.add_axes([0.13, 0.12, 0.7, 0.8])
    plot2Ddata(
        receiver_locations[:, 0:2],
        mag_data_plotting[0, :],
        ax=ax1,
        ncontour=30,
        clim=(-v_max, v_max),
        contourOpts={"cmap": "bwr"},
    )
    ax1.tick_params(width=0)
    ax1.set_xlabel("x direction [m]")
    ax1.set_ylabel("y direction [m]")
    ax1.ticklabel_format(axis='y', style='sci', scilimits=(0, 0))

    ax2 = fig.add_axes([0.85, 0.14, 0.03, 0.76])
    norm = mpl.colors.Normalize(vmin=v_min, vmax=v_max)
    cbar = mpl.colorbar.ColorbarBase(ax2,
                                     norm=norm,
                                     orientation="vertical",
                                     cmap=mpl.cm.bwr)
    cbar.set_label("Secondary field [T]", rotation=270, labelpad=15)
    ax2.tick_params(width=0)
    ax2.ticklabel_format(axis='y', style='sci', scilimits=(0, 0))
    def plot_survey_data(self, percentage, floor, seed, add_noise, plot_type,
                         update):
        self._percentage = percentage
        self._floor = floor
        self._seed = seed
        self._dobs = self.add_noise()
        self._data_prop.dobs = self._dobs.copy()

        fig, axs = plt.subplots(1, 2, figsize=(8, 4))
        out = self.mesh_prop.plotImage(1.0 / self.slowness_prop, ax=axs[0])
        cb = plt.colorbar(out[0], ax=axs[0], fraction=0.02)
        cb.set_label("Velocity (m/s)")
        self.survey_prop.plot(ax=axs[0])
        axs[0].set_title("Survey")
        axs[0].set_xlabel("x (m)")
        axs[0].set_ylabel("z (m)")

        x = np.arange(10) + 1
        y = np.arange(10) + 1
        xy = utils.ndgrid(x, y)
        if plot_type == "tx_rx_plane":
            if add_noise:
                out = utils.plot2Ddata(xy, self.dobs, ax=axs[1])
            else:
                out = utils.plot2Ddata(xy, self.pred, ax=axs[1])
            axs[1].set_xlabel("Rx")
            axs[1].set_ylabel("Tx")
            axs[1].set_xticks(x)
            axs[1].set_yticks(y)
            cb = plt.colorbar(out[0], ax=axs[1], fraction=0.02)
            cb.set_label("Traveltime (s)")
            for ax in axs:
                ax.set_aspect(1)
        else:
            if add_noise:
                out = axs[1].hist(self.pred, edgecolor="k")
            else:
                out = axs[1].hist(self.dobs, edgecolor="k")
            axs[1].set_ylabel("Count")
            axs[1].set_xlabel("Travel time (s)")
            axs[0].set_aspect(1)
        plt.tight_layout()
        plt.show()
dobs_mag = np.loadtxt(dir_path + "magnetic_data.obs")

# Define receiver locations and observed data
receiver_locations = dobs_grav[:, 0:3]

dobs_grav = dobs_grav[:, -1]
dobs_mag = dobs_mag[:, -1]

# Plot
mpl.rcParams.update({"font.size": 12})

# gravity data
fig = plt.figure(figsize=(7, 5))

ax1 = fig.add_axes([0.1, 0.1, 0.73, 0.85])
plot2Ddata(receiver_locations, dobs_grav, ax=ax1, contourOpts={"cmap": "bwr"})
ax1.set_title("Gravity Anomaly")
ax1.set_xlabel("x (m)")
ax1.set_ylabel("y (m)")

ax2 = fig.add_axes([0.8, 0.1, 0.03, 0.85])
norm = mpl.colors.Normalize(vmin=-np.max(np.abs(dobs_grav)),
                            vmax=np.max(np.abs(dobs_grav)))
cbar = mpl.colorbar.ColorbarBase(ax2,
                                 norm=norm,
                                 orientation="vertical",
                                 cmap=mpl.cm.bwr,
                                 format="%.1e")
cbar.set_label("$mgal$", rotation=270, labelpad=15, size=12)

# magnetic data
simulation = gravity.simulation.Simulation3DIntegral(
    survey=survey,
    mesh=mesh,
    rhoMap=model_map,
    actInd=ind_active,
    store_sensitivities="forward_only",
)

# Compute predicted data for some model
dpred = simulation.dpred(model)

# Plot
fig = plt.figure(figsize=(7, 5))

ax1 = fig.add_axes([0.1, 0.1, 0.75, 0.85])
plot2Ddata(receiver_list[0].locations, dpred, ax=ax1, contourOpts={"cmap": "bwr"})
ax1.set_title("Gravity Anomaly (Z-component)")
ax1.set_xlabel("x (m)")
ax1.set_ylabel("y (m)")

ax2 = fig.add_axes([0.82, 0.1, 0.03, 0.85])
norm = mpl.colors.Normalize(vmin=-np.max(np.abs(dpred)), vmax=np.max(np.abs(dpred)))
cbar = mpl.colorbar.ColorbarBase(
    ax2, norm=norm, orientation="vertical", cmap=mpl.cm.bwr, format="%.1e"
)
cbar.set_label("$mgal$", rotation=270, labelpad=15, size=12)

plt.show()


#######################################################
Exemple #8
0
    store_sensitivities="forward_only",
)

# Compute predicted data for some model
dpred = simulation.dpred(model)
n_data = len(dpred)

# Plot
fig = plt.figure(figsize=(13, 4))
v_max = np.max(np.abs(dpred))

ax1 = fig.add_axes([0.1, 0.15, 0.25, 0.78])
plot2Ddata(
    receiver_list[0].locations,
    dpred[0:n_data:3],
    ax=ax1,
    ncontour=30,
    clim=(-v_max, v_max),
    contourOpts={"cmap": "bwr"},
)
ax1.set_title("$dBz/dx$")
ax1.set_xlabel("x (m)")
ax1.set_ylabel("y (m)")

ax2 = fig.add_axes([0.36, 0.15, 0.25, 0.78])
cplot2 = plot2Ddata(
    receiver_list[0].locations,
    dpred[1:n_data:3],
    ax=ax2,
    ncontour=30,
    clim=(-v_max, v_max),
    contourOpts={"cmap": "bwr"},
Exemple #9
0
 def plot_magnetic_flux(self, itime):
     bxy, xy = self.getSlices(self.mesh,
                              self.B,
                              itime,
                              normal="Z",
                              loc=-100.5)
     byz, yz = self.getSlices(self.mesh, self.B, itime, normal="X", loc=0.0)
     label = "Magnetic flux density (T)"
     plt.figure(figsize=(12, 5))
     ax1 = plt.subplot(121)
     ax2 = plt.subplot(122)
     vmin, vmax = abs(np.r_[byz]).min(), abs(np.r_[byz]).max()
     out_yz = utils.plot2Ddata(yz,
                               byz,
                               vec=True,
                               ncontour=20,
                               contourOpts={"cmap": "viridis"},
                               ax=ax2)
     vmin, vmax = out_yz[0].get_clim()
     utils.plot2Ddata(
         xy,
         bxy,
         vec=True,
         ncontour=20,
         contourOpts={
             "cmap": "viridis",
             "vmin": vmin,
             "vmax": vmax
         },
         ax=ax1,
     )
     ax1.set_aspect("equal", adjustable="box")
     ax2.set_aspect("equal", adjustable="box")
     plt.colorbar(
         out_yz[0],
         ax=ax1,
         format="%.1e",
         ticks=np.linspace(vmin, vmax, 5),
         fraction=0.02,
     )
     cb = plt.colorbar(
         out_yz[0],
         ax=ax2,
         format="%.1e",
         ticks=np.linspace(vmin, vmax, 5),
         fraction=0.02,
     )
     cb.set_label(label)
     ax1.set_title("")
     ax1.set_xlabel("X (m)")
     ax1.set_ylabel("Y (m)")
     ax2.set_xlabel("Y (m)")
     ax2.set_ylabel("Z (m)")
     ax1.set_xlim(self.xmin, self.xmax)
     ax1.set_ylim(self.ymin, self.ymax)
     ax2.set_xlim(self.xmin, self.xmax)
     ax2.set_ylim(self.zmin, self.zmax)
     ax1.plot(ax1.get_xlim(), np.zeros(2), "k--", lw=1)
     ax2.plot(ax1.get_xlim(), np.zeros(2) - 100.0, "k--", lw=1)
     title = ("Time at %.2f ms") % ((self.times[itime]) * 1e3)
     ax1.set_title(title)
     plt.tight_layout()
def run(plotIt=True, saveFig=False, cleanup=True):
    """
    Run 1D inversions for a single sounding of the RESOLVE and SkyTEM
    bookpurnong data

    :param bool plotIt: show the plots?
    :param bool saveFig: save the figure
    :param bool cleanup: remove the downloaded results
    """
    downloads, directory = download_and_unzip_data()

    resolve = h5py.File(os.path.sep.join([directory, "booky_resolve.hdf5"]),
                        "r")
    skytem = h5py.File(os.path.sep.join([directory, "booky_skytem.hdf5"]), "r")
    river_path = resolve["river_path"].value

    # Choose a sounding location to invert
    xloc, yloc = 462100.0, 6196500.0
    rxind_skytem = np.argmin(
        abs(skytem["xy"][:, 0] - xloc) + abs(skytem["xy"][:, 1] - yloc))
    rxind_resolve = np.argmin(
        abs(resolve["xy"][:, 0] - xloc) + abs(resolve["xy"][:, 1] - yloc))

    # Plot both resolve and skytem data on 2D plane
    fig = plt.figure(figsize=(13, 6))
    title = ["RESOLVE In-phase 400 Hz", "SkyTEM High moment 156 $\mu$s"]
    ax1 = plt.subplot(121)
    ax2 = plt.subplot(122)
    axs = [ax1, ax2]
    out_re = utils.plot2Ddata(
        resolve["xy"],
        resolve["data"][:, 0],
        ncontour=100,
        contourOpts={"cmap": "viridis"},
        ax=ax1,
    )
    vmin, vmax = out_re[0].get_clim()
    cb_re = plt.colorbar(out_re[0],
                         ticks=np.linspace(vmin, vmax, 3),
                         ax=ax1,
                         fraction=0.046,
                         pad=0.04)
    temp_skytem = skytem["data"][:, 5].copy()
    temp_skytem[skytem["data"][:, 5] > 7e-10] = 7e-10
    out_sky = utils.plot2Ddata(
        skytem["xy"][:, :2],
        temp_skytem,
        ncontour=100,
        contourOpts={
            "cmap": "viridis",
            "vmax": 7e-10
        },
        ax=ax2,
    )
    vmin, vmax = out_sky[0].get_clim()
    cb_sky = plt.colorbar(
        out_sky[0],
        ticks=np.linspace(vmin, vmax * 0.99, 3),
        ax=ax2,
        format="%.1e",
        fraction=0.046,
        pad=0.04,
    )
    cb_re.set_label("Bz (ppm)")
    cb_sky.set_label("dB$_z$ / dt (V/A-m$^4$)")

    for i, ax in enumerate(axs):
        xticks = [460000, 463000]
        yticks = [6195000, 6198000, 6201000]
        ax.set_xticks(xticks)
        ax.set_yticks(yticks)
        ax.plot(xloc, yloc, "wo")
        ax.plot(river_path[:, 0], river_path[:, 1], "k", lw=0.5)

        ax.set_aspect("equal")
        if i == 1:
            ax.plot(skytem["xy"][:, 0],
                    skytem["xy"][:, 1],
                    "k.",
                    alpha=0.02,
                    ms=1)
            ax.set_yticklabels([str(" ") for f in yticks])
        else:
            ax.plot(resolve["xy"][:, 0],
                    resolve["xy"][:, 1],
                    "k.",
                    alpha=0.02,
                    ms=1)
            ax.set_yticklabels([str(f) for f in yticks])
            ax.set_ylabel("Northing (m)")
        ax.set_xlabel("Easting (m)")
        ax.set_title(title[i])
        ax.axis("equal")
    # plt.tight_layout()

    if saveFig is True:
        fig.savefig("resolve_skytem_data.png", dpi=600)

    # ------------------ Mesh ------------------ #
    # Step1: Set 2D cylindrical mesh
    cs, ncx, ncz, npad = 1.0, 10.0, 10.0, 20
    hx = [(cs, ncx), (cs, npad, 1.3)]
    npad = 12
    temp = np.logspace(np.log10(1.0), np.log10(12.0), 19)
    temp_pad = temp[-1] * 1.3**np.arange(npad)
    hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad]
    mesh = discretize.CylMesh([hx, 1, hz], "00C")
    active = mesh.vectorCCz < 0.0

    # Step2: Set a SurjectVertical1D mapping
    # Note: this sets our inversion model as 1D log conductivity
    # below subsurface

    active = mesh.vectorCCz < 0.0
    actMap = maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    mapping = maps.ExpMap(mesh) * maps.SurjectVertical1D(mesh) * actMap
    sig_half = 1e-1
    sig_air = 1e-8
    sigma = np.ones(mesh.nCz) * sig_air
    sigma[active] = sig_half

    # Initial and reference model
    m0 = np.log(sigma[active])

    # ------------------ RESOLVE Forward Simulation ------------------ #
    # Step3: Invert Resolve data

    # Bird height from the surface
    b_height_resolve = resolve["src_elevation"].value
    src_height_resolve = b_height_resolve[rxind_resolve]

    # Set Rx (In-phase and Quadrature)
    rxOffset = 7.86
    bzr = FDEM.Rx.PointMagneticFluxDensitySecondary(
        np.array([[rxOffset, 0.0, src_height_resolve]]),
        orientation="z",
        component="real",
    )

    bzi = FDEM.Rx.PointMagneticFluxDensity(
        np.array([[rxOffset, 0.0, src_height_resolve]]),
        orientation="z",
        component="imag",
    )

    # Set Source (In-phase and Quadrature)
    frequency_cp = resolve["frequency_cp"].value
    freqs = frequency_cp.copy()
    srcLoc = np.array([0.0, 0.0, src_height_resolve])
    srcList = [
        FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation="Z")
        for freq in freqs
    ]

    # Set FDEM survey (In-phase and Quadrature)
    survey = FDEM.Survey(srcList)
    prb = FDEM.Simulation3DMagneticFluxDensity(mesh,
                                               sigmaMap=mapping,
                                               Solver=Solver)
    prb.survey = survey

    # ------------------ RESOLVE Inversion ------------------ #

    # Primary field
    bp = -mu_0 / (4 * np.pi * rxOffset**3)

    # Observed data
    cpi_inds = [0, 2, 6, 8, 10]
    cpq_inds = [1, 3, 7, 9, 11]
    dobs_re = (np.c_[resolve["data"][rxind_resolve, :][cpi_inds],
                     resolve["data"][rxind_resolve, :][cpq_inds], ].flatten() *
               bp * 1e-6)

    # Uncertainty
    relative = np.repeat(np.r_[np.ones(3) * 0.1, np.ones(2) * 0.15], 2)
    floor = 20 * abs(bp) * 1e-6
    std = abs(dobs_re) * relative + floor

    # Data Misfit
    data_resolve = data.Data(dobs=dobs_re,
                             survey=survey,
                             standard_deviation=std)
    dmisfit = data_misfit.L2DataMisfit(simulation=prb, data=data_resolve)

    # Regularization
    regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = regularization.Simple(regMesh, mapping=maps.IdentityMap(regMesh))

    # Optimization
    opt = optimization.InexactGaussNewton(maxIter=5)

    # statement of the inverse problem
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)

    # Inversion directives and parameters
    target = directives.TargetMisfit()  # stop when we hit target misfit
    invProb.beta = 2.0
    inv = inversion.BaseInversion(invProb, directiveList=[target])
    reg.alpha_s = 1e-3
    reg.alpha_x = 1.0
    reg.mref = m0.copy()
    opt.LSshorten = 0.5
    opt.remember("xc")
    # run the inversion
    mopt_re = inv.run(m0)
    dpred_re = invProb.dpred

    # ------------------ SkyTEM Forward Simulation ------------------ #
    # Step4: Invert SkyTEM data

    # Bird height from the surface
    b_height_skytem = skytem["src_elevation"].value
    src_height = b_height_skytem[rxind_skytem]
    srcLoc = np.array([0.0, 0.0, src_height])

    # Radius of the source loop
    area = skytem["area"].value
    radius = np.sqrt(area / np.pi)
    rxLoc = np.array([[radius, 0.0, src_height]])

    # Parameters for current waveform
    t0 = skytem["t0"].value
    times = skytem["times"].value
    waveform_skytem = skytem["waveform"].value
    offTime = t0
    times_off = times - t0

    # Note: we are Using theoretical VTEM waveform,
    # but effectively fits SkyTEM waveform
    peakTime = 1.0000000e-02
    a = 3.0

    dbdt_z = TDEM.Rx.PointMagneticFluxTimeDerivative(
        locations=rxLoc, times=times_off[:-3] + offTime,
        orientation="z")  # vertical db_dt

    rxList = [dbdt_z]  # list of receivers
    srcList = [
        TDEM.Src.CircularLoop(
            rxList,
            loc=srcLoc,
            radius=radius,
            orientation="z",
            waveform=TDEM.Src.VTEMWaveform(offTime=offTime,
                                           peakTime=peakTime,
                                           a=3.0),
        )
    ]
    # solve the problem at these times
    timeSteps = [
        (peakTime / 5, 5),
        ((offTime - peakTime) / 5, 5),
        (1e-5, 5),
        (5e-5, 5),
        (1e-4, 10),
        (5e-4, 15),
    ]
    prob = TDEM.Simulation3DElectricField(mesh,
                                          time_steps=timeSteps,
                                          sigmaMap=mapping,
                                          Solver=Solver)
    survey = TDEM.Survey(srcList)
    prob.survey = survey

    src = srcList[0]
    rx = src.receiver_list[0]
    wave = []
    for time in prob.times:
        wave.append(src.waveform.eval(time))
    wave = np.hstack(wave)
    out = prob.dpred(m0)

    # plot the waveform
    fig = plt.figure(figsize=(5, 3))
    times_off = times - t0
    plt.plot(waveform_skytem[:, 0], waveform_skytem[:, 1], "k.")
    plt.plot(prob.times, wave, "k-", lw=2)
    plt.legend(("SkyTEM waveform", "Waveform (fit)"), fontsize=10)
    for t in rx.times:
        plt.plot(np.ones(2) * t, np.r_[-0.03, 0.03], "k-")
    plt.ylim(-0.1, 1.1)
    plt.grid(True)
    plt.xlabel("Time (s)")
    plt.ylabel("Normalized current")

    if saveFig:
        fig.savefig("skytem_waveform", dpi=200)

    # Observed data
    dobs_sky = skytem["data"][rxind_skytem, :-3] * area

    # ------------------ SkyTEM Inversion ------------------ #
    # Uncertainty
    relative = 0.12
    floor = 7.5e-12
    std = abs(dobs_sky) * relative + floor

    # Data Misfit
    data_sky = data.Data(dobs=-dobs_sky, survey=survey, standard_deviation=std)
    dmisfit = data_misfit.L2DataMisfit(simulation=prob, data=data_sky)

    # Regularization
    regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = regularization.Simple(regMesh, mapping=maps.IdentityMap(regMesh))

    # Optimization
    opt = optimization.InexactGaussNewton(maxIter=5)

    # statement of the inverse problem
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)

    # Directives and Inversion Parameters
    target = directives.TargetMisfit()
    invProb.beta = 20.0
    inv = inversion.BaseInversion(invProb, directiveList=[target])
    reg.alpha_s = 1e-1
    reg.alpha_x = 1.0
    opt.LSshorten = 0.5
    opt.remember("xc")
    reg.mref = mopt_re  # Use RESOLVE model as a reference model

    # run the inversion
    mopt_sky = inv.run(m0)
    dpred_sky = invProb.dpred

    # Plot the figure from the paper
    plt.figure(figsize=(12, 8))

    fs = 13  # fontsize
    matplotlib.rcParams["font.size"] = fs

    ax0 = plt.subplot2grid((2, 2), (0, 0), rowspan=2)
    ax1 = plt.subplot2grid((2, 2), (0, 1))
    ax2 = plt.subplot2grid((2, 2), (1, 1))

    # Recovered Models
    sigma_re = np.repeat(np.exp(mopt_re), 2, axis=0)
    sigma_sky = np.repeat(np.exp(mopt_sky), 2, axis=0)
    z = np.repeat(mesh.vectorCCz[active][1:], 2, axis=0)
    z = np.r_[mesh.vectorCCz[active][0], z, mesh.vectorCCz[active][-1]]

    ax0.semilogx(sigma_re, z, "k", lw=2, label="RESOLVE")
    ax0.semilogx(sigma_sky, z, "b", lw=2, label="SkyTEM")
    ax0.set_ylim(-50, 0)
    # ax0.set_xlim(5e-4, 1e2)
    ax0.grid(True)
    ax0.set_ylabel("Depth (m)")
    ax0.set_xlabel("Conducivity (S/m)")
    ax0.legend(loc=3)
    ax0.set_title("(a) Recovered Models")

    # RESOLVE Data
    ax1.loglog(frequency_cp,
               dobs_re.reshape((5, 2))[:, 0] / bp * 1e6,
               "k-",
               label="Obs (real)")
    ax1.loglog(
        frequency_cp,
        dobs_re.reshape((5, 2))[:, 1] / bp * 1e6,
        "k--",
        label="Obs (imag)",
    )
    ax1.loglog(
        frequency_cp,
        dpred_re.reshape((5, 2))[:, 0] / bp * 1e6,
        "k+",
        ms=10,
        markeredgewidth=2.0,
        label="Pred (real)",
    )
    ax1.loglog(
        frequency_cp,
        dpred_re.reshape((5, 2))[:, 1] / bp * 1e6,
        "ko",
        ms=6,
        markeredgecolor="k",
        markeredgewidth=0.5,
        label="Pred (imag)",
    )
    ax1.set_title("(b) RESOLVE")
    ax1.set_xlabel("Frequency (Hz)")
    ax1.set_ylabel("Bz (ppm)")
    ax1.grid(True)
    ax1.legend(loc=3, fontsize=11)

    # SkyTEM data
    ax2.loglog(times_off[3:] * 1e6, dobs_sky / area, "b-", label="Obs")
    ax2.loglog(
        times_off[3:] * 1e6,
        -dpred_sky / area,
        "bo",
        ms=4,
        markeredgecolor="k",
        markeredgewidth=0.5,
        label="Pred",
    )
    ax2.set_xlim(times_off.min() * 1e6 * 1.2, times_off.max() * 1e6 * 1.1)

    ax2.set_xlabel("Time ($\mu s$)")
    ax2.set_ylabel("dBz / dt (V/A-m$^4$)")
    ax2.set_title("(c) SkyTEM High-moment")
    ax2.grid(True)
    ax2.legend(loc=3)

    a3 = plt.axes([0.86, 0.33, 0.1, 0.09], facecolor=[0.8, 0.8, 0.8, 0.6])
    a3.plot(prob.times * 1e6, wave, "k-")
    a3.plot(rx.times * 1e6,
            np.zeros_like(rx.times),
            "k|",
            markeredgewidth=1,
            markersize=12)
    a3.set_xlim([prob.times.min() * 1e6 * 0.75, prob.times.max() * 1e6 * 1.1])
    a3.set_title("(d) Waveform", fontsize=11)
    a3.set_xticks([prob.times.min() * 1e6, t0 * 1e6, prob.times.max() * 1e6])
    a3.set_yticks([])
    # a3.set_xticklabels(['0', '2e4'])
    a3.set_xticklabels(["-1e4", "0", "1e4"])

    plt.tight_layout()

    if saveFig:
        plt.savefig("booky1D_time_freq.png", dpi=600)

    if plotIt:
        plt.show()

    resolve.close()
    skytem.close()
    if cleanup:
        print(os.path.split(directory)[:-1])
        os.remove(
            os.path.sep.join(directory.split()[:-1] +
                             ["._bookpurnong_inversion"]))
        os.remove(downloads)
        shutil.rmtree(directory)
Exemple #11
0
n_loc = locations.shape[0]
dpred = np.reshape(dpred, (n_loc, n_times))

# Plot
fig = plt.figure(figsize=(13, 5))

# Index for what time channel you would like to see the data map.
time_index = 10

v_max = np.max(np.abs(dpred[:, time_index]))
v_min = np.min(np.abs(dpred[:, time_index]))
ax11 = fig.add_axes([0.12, 0.1, 0.33, 0.85])
plot2Ddata(
    locations[:, 0:2],
    -dpred[:, time_index],
    ax=ax11,
    ncontour=30,
    clim=(v_min, v_max),
    contourOpts={"cmap": "magma_r"},
)
ax11.set_xlabel("x (m)")
ax11.set_ylabel("y (m)")
titlestr = "- dBz/dt at t=" + "{:.1e}".format(time_channels[time_index]) + " s"
ax11.set_title(titlestr)

ax12 = fig.add_axes([0.46, 0.1, 0.02, 0.85])
norm1 = mpl.colors.Normalize(vmin=v_min, vmax=v_max)
cbar1 = mpl.colorbar.ColorbarBase(ax12,
                                  norm=norm1,
                                  orientation="vertical",
                                  cmap=mpl.cm.magma_r)
cbar1.set_label("$T/s$", rotation=270, labelpad=15, size=12)
    def plotField(
        self,
        Field="B",
        view="vec",
        scale="linear",
        itime=0,
        Geometry=True,
        Scenario=None,
        Fixed=False,
        vmin=None,
        vmax=None,
    ):
        # Printout for null cases
        if (Field == "B") & (view == "y"):
            print(
                "Think about the problem geometry. There is NO By in this case."
            )
        elif (Field == "dBdt") & (view == "y"):
            print(
                "Think about the problem geometry. There is NO dBy/dt in this case."
            )
        elif (Field == "E") & (view == "x") | (Field == "E") & (view == "z"):
            print(
                "Think about the problem geometry. There is NO Ex or Ez in this case. Only Ey."
            )
        elif (Field == "J") & (view == "x") | (Field == "J") & (view == "z"):
            print(
                "Think about the problem geometry. There is NO Jx or Jz in this case. Only Jy."
            )
        elif (Field == "E") & (view == "vec"):
            print(
                "Think about the problem geometry. E only has components along y. Vector plot not possible"
            )
        elif (Field == "J") & (view == "vec"):
            print(
                "Think about the problem geometry. J only has components along y. Vector plot not possible"
            )
        elif Field == "Model":
            plt.figure(figsize=(7, 6))
            ax = plt.subplot(111)
            if Scenario == "Sphere":
                model2D, mapping2D = self.getCoreModel("Sphere")
            elif Scenario == "Layer":
                model2D, mapping2D = self.getCoreModel("Layer")

            if Fixed:
                clim = (np.log10(vmin), np.log10(vmax))
            else:
                clim = None
            out = self.mesh2D.plotImage(np.log10(mapping2D * model2D),
                                        ax=ax,
                                        clim=clim)
            cb = plt.colorbar(out[0], ax=ax, format="$10^{%.1f}$")
            cb.set_label("$\sigma$ (S/m)")
            ax.set_xlabel("Distance (m)")
            ax.set_ylabel("Depth (m)")
            ax.set_title("Conductivity Model")
            plt.show()
        else:
            plt.figure(figsize=(10, 6))
            ax = plt.subplot(111)
            vec = False
            if view == "vec":
                tname = "Vector "
                title = tname + Field + "-field"
            elif view == "amp":
                tname = "|"
                title = tname + Field + "|-field"
            else:
                title = Field + view + "-field"

            if Field == "B":
                label = "Magnetic field (T)"
                if view == "vec":
                    vec = True
                    val = np.c_[self.Bx, self.Bz]
                elif view == "x":
                    val = self.Bx
                elif view == "z":
                    val = self.Bz
                else:
                    return

            elif Field == "dBdt":
                label = "Time derivative of magnetic field (T/s)"
                if view == "vec":
                    vec = True
                    val = np.c_[self.dBxdt, self.dBzdt]
                elif view == "x":
                    val = self.dBxdt
                elif view == "z":
                    val = self.dBzdt
                else:
                    return

            elif Field == "E":
                label = "Electric field (V/m)"
                if view == "y":
                    val = self.Ey
                else:
                    return

            elif Field == "J":
                label = "Current density (A/m$^2$)"
                if view == "y":
                    val = self.Jy
                else:
                    return

            if Fixed:
                if scale == "log":
                    vmin, vmax = (np.log10(vmin), np.log10(vmax))
                out = ax.scatter(np.zeros(3) - 1000,
                                 np.zeros(3),
                                 c=np.linspace(vmin, vmax, 3))
                utils.plot2Ddata(
                    self.mesh2D.gridCC,
                    val,
                    vec=vec,
                    ax=ax,
                    contourOpts={
                        "cmap": "viridis",
                        "vmin": vmin,
                        "vmax": vmax
                    },
                    ncontour=200,
                    scale=scale,
                )

            else:
                out = utils.plot2Ddata(
                    self.mesh2D.gridCC,
                    val,
                    vec=vec,
                    ax=ax,
                    contourOpts={"cmap": "viridis"},
                    ncontour=200,
                    scale=scale,
                )[0]

            if scale == "linear":
                cb = plt.colorbar(out, ax=ax, format="%.2e")
            elif scale == "log":
                cb = plt.colorbar(out, ax=ax, format="$10^{%.1f}$")
            else:
                raise Exception("We consdier only linear and log scale!")
            cb.set_label(label)
            xmax = self.mesh2D.gridCC[:, 0].max()
            if Geometry:
                if Scenario == "Layer":
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.srcLoc[2],
                            "w-",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.z0,
                            "w--",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.z1,
                            "w--",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.z2,
                            "w--",
                            lw=1)
                    ax.plot(0, self.srcLoc[2], "ko", ms=4)
                    ax.plot(self.rxLoc[0, 0], self.srcLoc[2], "ro", ms=4)
                elif Scenario == "Sphere":
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.srcLoc[2],
                            "k-",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.z0,
                            "w--",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.z1,
                            "w--",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * (self.z1 - self.h),
                            "w--",
                            lw=1)
                    Phi = np.linspace(0, 2 * np.pi, 41)
                    ax.plot(
                        self.R * np.cos(Phi),
                        self.z2 + self.R * np.sin(Phi),
                        "w--",
                        lw=1,
                    )
                    ax.plot(0, self.srcLoc[2], "ko", ms=4)
                    ax.plot(self.rxLoc[0, 0], self.srcLoc[2], "ro", ms=4)

            ax.set_xlabel("Distance (m)")
            ax.set_ylabel("Depth (m)")
            title = (title + "\nt = " +
                     "{:.2e}".format(self.sim.times[itime] * 1e3) + " ms")
            ax.set_title(title)
            ax.set_xlim(-190, 190)
            ax.set_ylim(-190, 190)
            plt.show()
Exemple #13
0
# Load topography
xyz_topo = np.loadtxt(str(topo_filename))

# Load field data
dobs = np.loadtxt(str(data_filename))

# Define receiver locations and observed data
receiver_locations = dobs[:, 0:3]
dobs = dobs[:, -1]

# Plot
mpl.rcParams.update({"font.size": 12})
fig = plt.figure(figsize=(7, 5))

ax1 = fig.add_axes([0.1, 0.1, 0.73, 0.85])
plot2Ddata(receiver_locations, dobs, ax=ax1, contourOpts={"cmap": "bwr"})
ax1.set_title("Gravity Anomaly")
ax1.set_xlabel("x (m)")
ax1.set_ylabel("y (m)")

ax2 = fig.add_axes([0.8, 0.1, 0.03, 0.85])
norm = mpl.colors.Normalize(vmin=-np.max(np.abs(dobs)),
                            vmax=np.max(np.abs(dobs)))
cbar = mpl.colorbar.ColorbarBase(ax2,
                                 norm=norm,
                                 orientation="vertical",
                                 cmap=mpl.cm.bwr,
                                 format="%.1e")
cbar.set_label("$mgal$", rotation=270, labelpad=15, size=12)

plt.show()
Exemple #14
0
def run(plotIt=True, saveIt=False, saveFig=False, cleanup=True):
    """
    Download and plot the Bookpurnong data. Here, we parse the data into a
    dictionary that can be easily saved and loaded into other worflows (for
    later on when we are doing the inversion)

    :param bool plotIt: show the Figures?
    :param bool saveIt: re-save the parsed data?
    :param bool saveFig: save the matplotlib figures?
    :param bool cleanUp: remove the downloaded and saved data?
    """

    downloads, directory = download_and_unzip_data()

    # data are in a directory inside bookpurnong_inversion
    data_directory = os.path.sep.join([directory, "bookpurnong_data"])

    # Load RESOLVE (2008)
    header_resolve = "Survey     Date   Flight      fid  utctime helicopter_easting helicopter_northing gps_height bird_easting bird_northing bird_gpsheight elevation bird_height bird_roll bird_pitch bird_yaw    em[0]    em[1]    em[2]    em[3]    em[4]    em[5]    em[6]    em[7]    em[8]    em[9]   em[10]   em[11]       Line "
    header_resolve = header_resolve.split()
    resolve = np.loadtxt(
        os.path.sep.join([data_directory, "Bookpurnong_Resolve_Exported.XYZ"]),
        skiprows=8,
    )

    # Omit the cross lines
    resolve = resolve[(resolve[:, -1] > 30002) & (resolve[:, -1] < 38000), :]
    dat_header_resolve = "CPI400_F  CPQ400_F  CPI1800_F CPQ1800_F CXI3300_F CXQ3300_F CPI8200_F CPQ8200_F CPI40k_F  CPQ40k_F  CPI140k_F CPQ140k_F "
    dat_header_resolve = dat_header_resolve.split()

    xyz_resolve = resolve[:, 8:11]
    data_resolve = resolve[:, 16:-1]
    line_resolve = np.unique(resolve[:, -1])

    # Load SkyTEM (2006)
    fid = open(
        os.path.sep.join(
            [data_directory, "SK655CS_Bookpurnong_ZX_HM_TxInc_newDTM.txt"]
        ),
        "rb",
    )
    lines = fid.readlines()
    fid.close()
    header_skytem = lines[0].split()
    info_skytem = []
    data_skytem = []
    for i, line in enumerate(lines[1:]):
        if len(line.split()) != 65:
            info_skytem.append(np.array(line.split()[:16], dtype="O"))
            data_skytem.append(np.array(line.split()[16 : 16 + 24], dtype="float"))
        else:
            info_skytem.append(np.array(line.split()[:16], dtype="O"))
            data_skytem.append(np.array(line.split()[17 : 17 + 24], dtype="float"))
    info_skytem = np.vstack(info_skytem)
    data_skytem = np.vstack(data_skytem)
    lines_skytem = info_skytem[:, 1].astype(float)
    line_skytem = np.unique(lines_skytem)
    inds = lines_skytem < 2026
    info_skytem = info_skytem[inds, :]
    data_skytem = data_skytem[inds, :].astype(float)
    xyz_skytem = info_skytem[:, [13, 12]].astype(float)
    lines_skytem = info_skytem[:, 1].astype(float)
    line_skytem = np.unique(lines_skytem)

    # Load path of Murray River
    river_path = np.loadtxt(os.path.sep.join([directory, "MurrayRiver.txt"]))

    # Plot the data
    nskip = 40
    fig = plt.figure(figsize=(12 * 0.8, 6 * 0.8))
    title = ["Resolve In-phase 400 Hz", "SkyTEM High moment 156 $\mu$s"]
    ax1 = plt.subplot(121)
    ax2 = plt.subplot(122)
    axs = [ax1, ax2]
    out_re = utils.plot2Ddata(
        xyz_resolve[::nskip, :2],
        data_resolve[::nskip, 0],
        ncontour=100,
        contourOpts={"cmap": "viridis"},
        ax=ax1,
    )
    vmin, vmax = out_re[0].get_clim()
    cb_re = plt.colorbar(
        out_re[0], ticks=np.linspace(vmin, vmax, 3), ax=ax1, fraction=0.046, pad=0.04
    )
    temp_skytem = data_skytem[:, 5].copy()
    temp_skytem[data_skytem[:, 5] > 7e-10] = 7e-10
    out_sky = utils.plot2Ddata(
        xyz_skytem[:, :2],
        temp_skytem,
        ncontour=100,
        contourOpts={"cmap": "viridis", "vmax": 7e-10},
        ax=ax2,
    )
    vmin, vmax = out_sky[0].get_clim()
    cb_sky = plt.colorbar(
        out_sky[0],
        ticks=np.linspace(vmin, vmax, 3),
        ax=ax2,
        format="%.1e",
        fraction=0.046,
        pad=0.04,
    )
    cb_re.set_label("Bz (ppm)")
    cb_sky.set_label("Voltage (V/A-m$^4$)")

    for i, ax in enumerate(axs):
        xticks = [460000, 463000]
        yticks = [6195000, 6198000, 6201000]
        ax.set_xticks(xticks)
        ax.set_yticks(yticks)
        ax.plot(river_path[:, 0], river_path[:, 1], "k", lw=0.5)

        ax.set_aspect("equal")
        if i == 1:
            ax.plot(xyz_skytem[:, 0], xyz_skytem[:, 1], "k.", alpha=0.02, ms=1)
            ax.set_yticklabels([str(" ") for f in yticks])
        else:
            ax.plot(xyz_resolve[:, 0], xyz_resolve[:, 1], "k.", alpha=0.02, ms=1)
            ax.set_yticklabels([str(f) for f in yticks])
            ax.set_ylabel("Northing (m)")
        ax.set_xlabel("Easting (m)")
        ax.set_title(title[i])
    plt.tight_layout()

    if plotIt:
        plt.show()

    if saveFig:
        fig.savefig("bookpurnong_data.png")

    cs, ncx, ncz, npad = 1.0, 10.0, 10.0, 20
    hx = [(cs, ncx), (cs, npad, 1.3)]
    npad = 12
    temp = np.logspace(np.log10(1.0), np.log10(12.0), 19)
    temp_pad = temp[-1] * 1.3 ** np.arange(npad)
    hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad]
    mesh = discretize.CylMesh([hx, 1, hz], "00C")
    active = mesh.vectorCCz < 0.0

    dobs_re = np.load(os.path.sep.join([directory, "dobs_re_final.npy"]))
    dpred_re = np.load(os.path.sep.join([directory, "dpred_re_final.npy"]))
    mopt_re = np.load(os.path.sep.join([directory, "mopt_re_final.npy"]))

    # Down sample resolve data
    nskip = 40
    inds_resolve = np.r_[np.array(range(0, data_resolve.shape[0] - 1, nskip)), 16730]

    booky_resolve = {
        "data": data_resolve[inds_resolve, :],
        "data_header": dat_header_resolve,
        "line": resolve[:, -1][inds_resolve],
        "xy": xyz_resolve[:, :2][inds_resolve],
        "src_elevation": resolve[:, 12][inds_resolve],
        "ground_elevation": resolve[:, 11][inds_resolve],
        "dobs": dobs_re,
        "dpred": dpred_re,
        "mopt": mopt_re,
        "z": mesh.vectorCCz[active],
        "frequency_cp": np.r_[382, 1822, 7970, 35920, 130100],
        "frequency_cx": np.r_[3258.0],
        "river_path": river_path,
    }

    area = 314.0
    waveform = np.loadtxt(os.path.sep.join([directory, "skytem_hm.wf"]))
    times = np.loadtxt(os.path.sep.join([directory, "skytem_hm.tc"]))

    booky_skytem = {
        "data": data_skytem,
        "data_header": header_skytem[17 : 17 + 24],
        "line": lines_skytem,
        "xy": xyz_skytem,
        "src_elevation": info_skytem[:, 10].astype(float),
        "ground_elevation": info_skytem[:, 15].astype(float),
        "area": area,
        "radius": np.sqrt(area / np.pi),
        "t0": 0.01004,
        "waveform": waveform,
        "times": times,
    }

    if saveIt:
        save_dict_to_hdf5(
            os.path.sep.join([directory, "booky_resolve.hdf5"]), booky_resolve
        )
        save_dict_to_hdf5(
            os.path.sep.join([directory, "booky_skytem.hdf5"]), booky_skytem
        )

    if cleanup:
        os.remove(downloads)
        shutil.rmtree(directory)
Exemple #15
0
    def plotField(
        self,
        Field="B",
        ComplexNumber="real",
        view="vec",
        scale="linear",
        Frequency=100,
        Geometry=True,
        Scenario=None,
    ):
        # Printout for null cases
        if (Field == "B") & (view == "y"):
            print(
                "Think about the problem geometry. There is NO By in this case."
            )
        elif (Field == "E") & (view == "x") | (Field == "E") & (view == "z"):
            print(
                "Think about the problem geometry. There is NO Ex or Ez in this case. Only Ey."
            )
        elif (Field == "J") & (view == "x") | (Field == "J") & (view == "z"):
            print(
                "Think about the problem geometry. There is NO Jx or Jz in this case. Only Jy."
            )
        elif (Field == "E") & (view == "vec"):
            print(
                "Think about the problem geometry. E only has components along y. Vector plot not possible"
            )
        elif (Field == "J") & (view == "vec"):
            print(
                "Think about the problem geometry. J only has components along y. Vector plot not possible"
            )
        elif (view == "vec") & (ComplexNumber == "Amp") | (view == "vec") & (
                ComplexNumber == "Phase"):
            print(
                "Cannot show amplitude or phase when vector plot selected. Set 'AmpDir=None' to see amplitude or phase."
            )
        elif Field == "Model":
            plt.figure(figsize=(7, 6))
            ax = plt.subplot(111)
            if Scenario == "Sphere":
                model2D, mapping2D = self.getCoreModel("Sphere")
            elif Scenario == "Layer":
                model2D, mapping2D = self.getCoreModel("Layer")

            out = self.mesh2D.plotImage(np.log10(mapping2D * model2D), ax=ax)
            cb = plt.colorbar(out[0], ax=ax, format="$10^{%.1f}$")
            cb.set_label("$\sigma$ (S/m)")
            ax.set_xlabel("Distance (m)")
            ax.set_ylabel("Depth (m)")
            ax.set_title("Conductivity Model")
            plt.show()
        else:
            plt.figure(figsize=(10, 6))
            ax = plt.subplot(111)
            vec = False
            if view == "vec":
                tname = "Vector "
                title = tname + Field + "-field"
            elif view == "amp":
                tname = "|"
                title = tname + Field + "|-field"
            else:
                if ComplexNumber == "real":
                    tname = "Re("
                elif ComplexNumber == "imag":
                    tname = "Im("
                elif ComplexNumber == "amplitude":
                    tname = "Amp("
                elif ComplexNumber == "phase":
                    tname = "Phase("
                title = tname + Field + view + ")-field"

            if Field == "B":
                label = "Magnetic field (T)"
                if view == "vec":
                    vec = True
                    if ComplexNumber == "real":
                        val = np.c_[self.Bx.real, self.Bz.real]
                    elif ComplexNumber == "imag":
                        val = np.c_[self.Bx.imag, self.Bz.imag]
                    else:
                        return

                elif view == "x":
                    if ComplexNumber == "real":
                        val = self.Bx.real
                    elif ComplexNumber == "imag":
                        val = self.Bx.imag
                    elif ComplexNumber == "amplitude":
                        val = abs(self.Bx)
                    elif ComplexNumber == "phase":
                        val = np.angle(self.Bx)
                elif view == "z":
                    if ComplexNumber == "real":
                        val = self.Bz.real
                    elif ComplexNumber == "imag":
                        val = self.Bz.imag
                    elif ComplexNumber == "amplitude":
                        val = abs(self.Bz)
                    elif ComplexNumber == "phase":
                        val = np.angle(self.Bz)
                else:
                    return

            elif Field == "E":
                label = "Electric field (V/m)"
                if view == "y":
                    if ComplexNumber == "real":
                        val = self.Ey.real
                    elif ComplexNumber == "imag":
                        val = self.Ey.imag
                    elif ComplexNumber == "amplitude":
                        val = abs(self.Ey)
                    elif ComplexNumber == "phase":
                        val = np.angle(self.Ey)
                else:
                    return

            elif Field == "J":
                label = "Current density (A/m$^2$)"
                if view == "y":
                    if ComplexNumber == "real":
                        val = self.Jy.real
                    elif ComplexNumber == "imag":
                        val = self.Jy.imag
                    elif ComplexNumber == "amplitude":
                        val = abs(self.Jy)
                    elif ComplexNumber == "phase":
                        val = np.angle(self.Jy)
                else:
                    return

            out = utils.plot2Ddata(
                self.mesh2D.gridCC,
                val,
                vec=vec,
                ax=ax,
                contourOpts={"cmap": "viridis"},
                ncontour=200,
                scale=scale,
            )
            cb = plt.colorbar(out[0], ax=ax, format="%.2e")
            cb.set_label(label)
            xmax = self.mesh2D.gridCC[:, 0].max()
            if Geometry:
                if Scenario == "Layer":
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.srcLoc[2],
                            "w-",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.z0,
                            "w--",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.z1,
                            "w--",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.z2,
                            "w--",
                            lw=1)
                    ax.plot(0, self.srcLoc[2], "ko", ms=4)
                    ax.plot(self.rxLoc[0, 0], self.srcLoc[2], "ro", ms=4)
                elif Scenario == "Sphere":
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.srcLoc[2],
                            "k-",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.z0,
                            "w--",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * self.z1,
                            "w--",
                            lw=1)
                    ax.plot(np.r_[-xmax, xmax],
                            np.ones(2) * (self.z1 - self.h),
                            "w--",
                            lw=1)
                    Phi = np.linspace(0, 2 * np.pi, 41)
                    ax.plot(
                        self.R * np.cos(Phi),
                        self.z2 + self.R * np.sin(Phi),
                        "w--",
                        lw=1,
                    )
                    ax.plot(0, self.srcLoc[2], "ko", ms=4)
                    ax.plot(self.rxLoc[0, 0], self.srcLoc[2], "ro", ms=4)

            ax.set_xlabel("Distance (m)")
            ax.set_ylabel("Depth (m)")
            title = title + "\nf = " + "{:.2e}".format(Frequency) + " Hz"
            ax.set_title(title)
            plt.show()
dobs_imag = dobs[:, 5]

# Plot the data
unique_frequencies = np.unique(frequencies)
frequency_index = 0
k = frequencies == unique_frequencies[frequency_index]

fig = plt.figure(figsize=(10, 4))

# Real Component
v_max = np.max(np.abs(dobs_real[k]))
ax1 = fig.add_axes([0.05, 0.05, 0.35, 0.9])
plot2Ddata(
    receiver_locations[k, 0:2],
    dobs_real[k],
    ax=ax1,
    ncontour=30,
    clim=(-v_max, v_max),
    contourOpts={"cmap": "RdBu_r"},
)
ax1.set_title("Re[$B_z$] at 200 Hz")

ax2 = fig.add_axes([0.41, 0.05, 0.02, 0.9])
norm = mpl.colors.Normalize(vmin=-v_max, vmax=v_max)
cbar = mpl.colorbar.ColorbarBase(ax2,
                                 norm=norm,
                                 orientation="vertical",
                                 cmap=mpl.cm.RdBu_r)
cbar.set_label("$T$", rotation=270, labelpad=15, size=12)

# Imaginary Component
v_max = np.max(np.abs(dobs_imag[k]))
Exemple #17
0
bz_imag = dpred[1:len(dpred):2]

# Then we will will reshape the data for plotting.
bz_real_plotting = np.reshape(bz_real, (len(frequencies), ntx))
bz_imag_plotting = np.reshape(bz_imag, (len(frequencies), ntx))

fig = plt.figure(figsize=(10, 4))

# Real Component
frequencies_index = 0
v_max = np.max(np.abs(bz_real_plotting[frequencies_index, :]))
ax1 = fig.add_axes([0.05, 0.05, 0.35, 0.9])
plot2Ddata(
    receiver_locations[:, 0:2],
    bz_real_plotting[frequencies_index, :],
    ax=ax1,
    ncontour=30,
    clim=(-v_max, v_max),
    contourOpts={"cmap": "bwr"},
)
ax1.set_title("Re[$B_z$] at 100 Hz")

ax2 = fig.add_axes([0.41, 0.05, 0.02, 0.9])
norm = mpl.colors.Normalize(vmin=-v_max, vmax=v_max)
cbar = mpl.colorbar.ColorbarBase(ax2,
                                 norm=norm,
                                 orientation="vertical",
                                 cmap=mpl.cm.bwr)
cbar.set_label("$T$", rotation=270, labelpad=15, size=12)

# Imaginary Component
v_max = np.max(np.abs(bz_imag_plotting[frequencies_index, :]))
Exemple #18
0
def run(plotIt=True, cleanAfterRun=True):

    # Start by downloading files from the remote repository
    # directory where the downloaded files are

    url = "https://storage.googleapis.com/simpeg/Chile_GRAV_4_Miller/Chile_GRAV_4_Miller.tar.gz"
    downloads = download(url, overwrite=True)
    basePath = downloads.split(".")[0]

    # unzip the tarfile
    tar = tarfile.open(downloads, "r")
    tar.extractall()
    tar.close()

    input_file = basePath + os.path.sep + "LdM_input_file.inp"
    # %% User input
    # Plotting parameters, max and min densities in g/cc
    vmin = -0.6
    vmax = 0.6

    # weight exponent for default weighting
    wgtexp = 3.0
    # %%
    # Read in the input file which included all parameters at once
    # (mesh, topo, model, survey, inv param, etc.)
    driver = GravityDriver_Inv(input_file)
    # %%
    # Now we need to create the survey and model information.

    # Access the mesh and survey information
    mesh = driver.mesh  #
    survey = driver.survey
    data_object = driver.data
    # [survey, data_object] = driver.survey

    # define gravity survey locations
    rxLoc = survey.source_field.receiver_list[0].locations

    # define gravity data and errors
    d = data_object.dobs

    # Get the active cells
    active = driver.activeCells
    nC = len(active)  # Number of active cells

    # Create active map to go from reduce set to full
    activeMap = maps.InjectActiveCells(mesh, active, -100)

    # Create static map
    static = driver.staticCells
    dynamic = driver.dynamicCells

    staticCells = maps.InjectActiveCells(None,
                                         dynamic,
                                         driver.m0[static],
                                         nC=nC)
    mstart = driver.m0[dynamic]

    # Get index of the center
    midx = int(mesh.nCx / 2)
    # %%
    # Now that we have a model and a survey we can build the linear system ...
    # Create the forward model operator
    simulation = gravity.simulation.Simulation3DIntegral(survey=survey,
                                                         mesh=mesh,
                                                         rhoMap=staticCells,
                                                         actInd=active)

    # %% Create inversion objects
    reg = regularization.Sparse(mesh,
                                indActive=active,
                                mapping=staticCells,
                                gradientType="total")
    reg.mref = driver.mref[dynamic]

    reg.norms = np.c_[0.0, 1.0, 1.0, 1.0]
    # reg.norms = driver.lpnorms

    # Specify how the optimization will proceed
    opt = optimization.ProjectedGNCG(
        maxIter=20,
        lower=driver.bounds[0],
        upper=driver.bounds[1],
        maxIterLS=10,
        maxIterCG=20,
        tolCG=1e-4,
    )

    # Define misfit function (obs-calc)
    dmis = data_misfit.L2DataMisfit(data=data_object, simulation=simulation)

    # create the default L2 inverse problem from the above objects
    invProb = inverse_problem.BaseInvProblem(dmis, reg, opt)

    # Specify how the initial beta is found
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1e-2)

    # IRLS sets up the Lp inversion problem
    # Set the eps parameter parameter in Line 11 of the
    # input file based on the distribution of model (DEFAULT = 95th %ile)
    IRLS = directives.Update_IRLS(f_min_change=1e-4,
                                  max_irls_iterations=40,
                                  coolEpsFact=1.5,
                                  beta_tol=5e-1)

    # Preconditioning refreshing for each IRLS iteration
    update_Jacobi = directives.UpdatePreconditioner()
    sensitivity_weights = directives.UpdateSensitivityWeights()

    # Create combined the L2 and Lp problem
    inv = inversion.BaseInversion(
        invProb,
        directiveList=[sensitivity_weights, IRLS, update_Jacobi, betaest])

    # %%
    # Run L2 and Lp inversion
    mrec = inv.run(mstart)

    if cleanAfterRun:
        os.remove(downloads)
        shutil.rmtree(basePath)

    # %%
    if plotIt:
        # Plot observed data
        # The sign of the data is flipped here for the change of convention
        # between Cartesian coordinate system (internal SimPEG format that
        # expects "positive up" gravity signal) and traditional gravity data
        # conventions (positive down). For example a traditional negative
        # gravity anomaly is described as "positive up" in Cartesian coordinates
        # and hence the sign needs to be flipped for use in SimPEG.
        plot2Ddata(rxLoc, -d)

        # %%
        # Write output model and data files and print misfit stats.

        # reconstructing l2 model mesh with air cells and active dynamic cells
        L2out = activeMap * invProb.l2model

        # reconstructing lp model mesh with air cells and active dynamic cells
        Lpout = activeMap * mrec

        # %%
        # Plot out sections and histograms of the smooth l2 model.
        # The ind= parameter is the slice of the model from top down.
        yslice = midx + 1
        L2out[L2out == -100] = np.nan  # set "air" to nan

        plt.figure(figsize=(10, 7))
        plt.suptitle("Smooth Inversion: Depth weight = " + str(wgtexp))
        ax = plt.subplot(221)
        dat1 = mesh.plotSlice(
            L2out,
            ax=ax,
            normal="Z",
            ind=-16,
            clim=(vmin, vmax),
            pcolorOpts={"cmap": "bwr"},
        )
        plt.plot(
            np.array([mesh.vectorCCx[0], mesh.vectorCCx[-1]]),
            np.array([mesh.vectorCCy[yslice], mesh.vectorCCy[yslice]]),
            c="gray",
            linestyle="--",
        )
        plt.scatter(rxLoc[0:, 0], rxLoc[0:, 1], color="k", s=1)
        plt.title("Z: " + str(mesh.vectorCCz[-16]) + " m")
        plt.xlabel("Easting (m)")
        plt.ylabel("Northing (m)")
        plt.gca().set_aspect("equal", adjustable="box")
        cb = plt.colorbar(dat1[0],
                          orientation="vertical",
                          ticks=np.linspace(vmin, vmax, 4))
        cb.set_label("Density (g/cc$^3$)")

        ax = plt.subplot(222)
        dat = mesh.plotSlice(
            L2out,
            ax=ax,
            normal="Z",
            ind=-27,
            clim=(vmin, vmax),
            pcolorOpts={"cmap": "bwr"},
        )
        plt.plot(
            np.array([mesh.vectorCCx[0], mesh.vectorCCx[-1]]),
            np.array([mesh.vectorCCy[yslice], mesh.vectorCCy[yslice]]),
            c="gray",
            linestyle="--",
        )
        plt.scatter(rxLoc[0:, 0], rxLoc[0:, 1], color="k", s=1)
        plt.title("Z: " + str(mesh.vectorCCz[-27]) + " m")
        plt.xlabel("Easting (m)")
        plt.ylabel("Northing (m)")
        plt.gca().set_aspect("equal", adjustable="box")
        cb = plt.colorbar(dat1[0],
                          orientation="vertical",
                          ticks=np.linspace(vmin, vmax, 4))
        cb.set_label("Density (g/cc$^3$)")

        ax = plt.subplot(212)
        mesh.plotSlice(
            L2out,
            ax=ax,
            normal="Y",
            ind=yslice,
            clim=(vmin, vmax),
            pcolorOpts={"cmap": "bwr"},
        )
        plt.title("Cross Section")
        plt.xlabel("Easting(m)")
        plt.ylabel("Elevation")
        plt.gca().set_aspect("equal", adjustable="box")
        cb = plt.colorbar(
            dat1[0],
            orientation="vertical",
            ticks=np.linspace(vmin, vmax, 4),
            cmap="bwr",
        )
        cb.set_label("Density (g/cc$^3$)")

        # %%
        # Make plots of Lp model
        yslice = midx + 1
        Lpout[Lpout == -100] = np.nan  # set "air" to nan

        plt.figure(figsize=(10, 7))
        plt.suptitle("Compact Inversion: Depth weight = " + str(wgtexp) +
                     ": $\epsilon_p$ = " + str(round(reg.eps_p, 1)) +
                     ": $\epsilon_q$ = " + str(round(reg.eps_q, 2)))
        ax = plt.subplot(221)
        dat = mesh.plotSlice(
            Lpout,
            ax=ax,
            normal="Z",
            ind=-16,
            clim=(vmin, vmax),
            pcolorOpts={"cmap": "bwr"},
        )
        plt.plot(
            np.array([mesh.vectorCCx[0], mesh.vectorCCx[-1]]),
            np.array([mesh.vectorCCy[yslice], mesh.vectorCCy[yslice]]),
            c="gray",
            linestyle="--",
        )
        plt.scatter(rxLoc[0:, 0], rxLoc[0:, 1], color="k", s=1)
        plt.title("Z: " + str(mesh.vectorCCz[-16]) + " m")
        plt.xlabel("Easting (m)")
        plt.ylabel("Northing (m)")
        plt.gca().set_aspect("equal", adjustable="box")
        cb = plt.colorbar(dat[0],
                          orientation="vertical",
                          ticks=np.linspace(vmin, vmax, 4))
        cb.set_label("Density (g/cc$^3$)")

        ax = plt.subplot(222)
        dat = mesh.plotSlice(
            Lpout,
            ax=ax,
            normal="Z",
            ind=-27,
            clim=(vmin, vmax),
            pcolorOpts={"cmap": "bwr"},
        )
        plt.plot(
            np.array([mesh.vectorCCx[0], mesh.vectorCCx[-1]]),
            np.array([mesh.vectorCCy[yslice], mesh.vectorCCy[yslice]]),
            c="gray",
            linestyle="--",
        )
        plt.scatter(rxLoc[0:, 0], rxLoc[0:, 1], color="k", s=1)
        plt.title("Z: " + str(mesh.vectorCCz[-27]) + " m")
        plt.xlabel("Easting (m)")
        plt.ylabel("Northing (m)")
        plt.gca().set_aspect("equal", adjustable="box")
        cb = plt.colorbar(dat[0],
                          orientation="vertical",
                          ticks=np.linspace(vmin, vmax, 4))
        cb.set_label("Density (g/cc$^3$)")

        ax = plt.subplot(212)
        dat = mesh.plotSlice(
            Lpout,
            ax=ax,
            normal="Y",
            ind=yslice,
            clim=(vmin, vmax),
            pcolorOpts={"cmap": "bwr"},
        )
        plt.title("Cross Section")
        plt.xlabel("Easting (m)")
        plt.ylabel("Elevation (m)")
        plt.gca().set_aspect("equal", adjustable="box")
        cb = plt.colorbar(dat[0],
                          orientation="vertical",
                          ticks=np.linspace(vmin, vmax, 4))
        cb.set_label("Density (g/cc$^3$)")
Exemple #19
0
# Predict data for a given model
dpred = simulation.dpred(model)

# Data were organized by location, then by time channel
dpred_plotting = np.reshape(dpred, (n_tx**2, n_times))

# Plot
fig = plt.figure(figsize=(10, 4))

# dB/dt at early time
v_max = np.max(np.abs(dpred_plotting[:, 0]))
ax11 = fig.add_axes([0.05, 0.05, 0.35, 0.9])
plot2Ddata(
    receiver_locations[:, 0:2],
    dpred_plotting[:, 0],
    ax=ax11,
    ncontour=30,
    clim=(-v_max, v_max),
    contourOpts={"cmap": "bwr"},
)
ax11.set_title("dBz/dt at 0.0001 s")

ax12 = fig.add_axes([0.42, 0.05, 0.02, 0.9])
norm1 = mpl.colors.Normalize(vmin=-v_max, vmax=v_max)
cbar1 = mpl.colorbar.ColorbarBase(ax12,
                                  norm=norm1,
                                  orientation="vertical",
                                  cmap=mpl.cm.bwr)
cbar1.set_label("$T/s$", rotation=270, labelpad=15, size=12)

# dB/dt at later times
v_max = np.max(np.abs(dpred_plotting[:, -1]))
def run(runIt=False, plotIt=True, saveIt=False, saveFig=False, cleanup=True):
    """
    Run the bookpurnong 1D stitched RESOLVE inversions.

    :param bool runIt: re-run the inversions? Default downloads and plots saved results
    :param bool plotIt: show the plots?
    :param bool saveIt: save the re-inverted results?
    :param bool saveFig: save the figure
    :param bool cleanup: remove the downloaded results
    """

    # download the data
    downloads, directory = download_and_unzip_data()

    # Load resolve data
    resolve = h5py.File(os.path.sep.join([directory, "booky_resolve.hdf5"]),
                        "r")

    river_path = resolve["river_path"][()]  # River path
    nSounding = resolve["data"].shape[0]  # the # of soundings

    # Bird height from surface
    b_height_resolve = resolve["src_elevation"][()]

    # fetch the frequencies we are considering
    cpi_inds = [0, 2, 6, 8, 10]  # Indices for HCP in-phase
    cpq_inds = [1, 3, 7, 9, 11]  # Indices for HCP quadrature
    frequency_cp = resolve["frequency_cp"][()]

    # build a mesh
    cs, ncx, ncz, npad = 1.0, 10.0, 10.0, 20
    hx = [(cs, ncx), (cs, npad, 1.3)]
    npad = 12
    temp = np.logspace(np.log10(1.0), np.log10(12.0), 19)
    temp_pad = temp[-1] * 1.3**np.arange(npad)
    hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad]
    mesh = discretize.CylMesh([hx, 1, hz], "00C")
    active = mesh.vectorCCz < 0.0

    # survey parameters
    rxOffset = 7.86  # tx-rx separation
    bp = -mu_0 / (4 * np.pi * rxOffset**3)  # primary magnetic field

    # re-run the inversion
    if runIt:

        # set up the mappings - we are inverting for 1D log conductivity
        # below the earth's surface.
        actMap = maps.InjectActiveCells(mesh,
                                        active,
                                        np.log(1e-8),
                                        nC=mesh.nCz)
        mapping = maps.ExpMap(mesh) * maps.SurjectVertical1D(mesh) * actMap

        # build starting and reference model
        sig_half = 1e-1
        sig_air = 1e-8
        sigma = np.ones(mesh.nCz) * sig_air
        sigma[active] = sig_half
        m0 = np.log(1e-1) * np.ones(active.sum())  # starting model
        mref = np.log(1e-1) * np.ones(active.sum())  # reference model

        # initalize empty lists for storing inversion results
        mopt_re = []  # recovered model
        dpred_re = []  # predicted data
        dobs_re = []  # observed data

        # downsample the data for the inversion
        nskip = 40

        # set up a noise model
        # 10% for the 3 lowest frequencies, 15% for the two highest
        relative = np.repeat(np.r_[np.ones(3) * 0.1, np.ones(2) * 0.15], 2)
        floor = abs(20 * bp * 1e-6)  # floor of 20ppm

        # loop over the soundings and invert each
        for rxind in range(nSounding):

            # convert data from ppm to magnetic field (A/m^2)
            dobs = (np.c_[resolve["data"][rxind, :][cpi_inds].astype(float),
                          resolve["data"][
                              rxind, :][cpq_inds].astype(float), ].flatten() *
                    bp * 1e-6)

            # perform the inversion
            src_height = b_height_resolve[rxind].astype(float)
            mopt, dpred, dobs = resolve_1Dinversions(
                mesh,
                dobs,
                src_height,
                frequency_cp,
                m0,
                mref,
                mapping,
                relative=relative,
                floor=floor,
            )

            # add results to our list
            mopt_re.append(mopt)
            dpred_re.append(dpred)
            dobs_re.append(dobs)

        # save results
        mopt_re = np.vstack(mopt_re)
        dpred_re = np.vstack(dpred_re)
        dobs_re = np.vstack(dobs_re)

        if saveIt:
            np.save("mopt_re_final", mopt_re)
            np.save("dobs_re_final", dobs_re)
            np.save("dpred_re_final", dpred_re)

    mopt_re = resolve["mopt"][()]
    dobs_re = resolve["dobs"][()]
    dpred_re = resolve["dpred"][()]

    sigma = np.exp(mopt_re)
    indz = -7  # depth index

    # so that we can visually compare with literature (eg Viezzoli, 2010)
    cmap = "jet"

    # dummy figure for colobar
    fig = plt.figure()
    out = plt.scatter(np.ones(3),
                      np.ones(3),
                      c=np.linspace(-2, 1, 3),
                      cmap=cmap)
    plt.close(fig)

    # plot from the paper
    fs = 13  # fontsize
    # matplotlib.rcParams['font.size'] = fs
    plt.figure(figsize=(13, 7))
    ax0 = plt.subplot2grid((2, 3), (0, 0), rowspan=2, colspan=2)
    ax1 = plt.subplot2grid((2, 3), (0, 2))
    ax2 = plt.subplot2grid((2, 3), (1, 2))

    # titles of plots
    title = [
        ("(a) Recovered model, %.1f m depth") %
        (-mesh.vectorCCz[active][indz]),
        "(b) Obs (Real 400 Hz)",
        "(c) Pred (Real 400 Hz)",
    ]

    temp = sigma[:, indz]
    tree = cKDTree(list(zip(resolve["xy"][:, 0], resolve["xy"][:, 1])))
    d, d_inds = tree.query(list(zip(resolve["xy"][:, 0], resolve["xy"][:, 1])),
                           k=20)
    w = 1.0 / (d + 100.0)**2.0
    w = utils.sdiag(1.0 / np.sum(w, axis=1)) * (w)
    xy = resolve["xy"]
    temp = (temp.flatten()[d_inds] * w).sum(axis=1)
    utils.plot2Ddata(
        xy,
        temp,
        ncontour=100,
        scale="log",
        dataloc=False,
        contourOpts={
            "cmap": cmap,
            "vmin": 1e-2,
            "vmax": 1e1
        },
        ax=ax0,
    )
    ax0.plot(resolve["xy"][:, 0], resolve["xy"][:, 1], "k.", alpha=0.02, ms=1)

    cb = plt.colorbar(out,
                      ax=ax0,
                      ticks=np.linspace(-2, 1, 4),
                      format="$10^{%.1f}$")
    cb.set_ticklabels(["0.01", "0.1", "1", "10"])
    cb.set_label("Conductivity (S/m)")
    ax0.plot(river_path[:, 0], river_path[:, 1], "k-", lw=0.5)

    # plot observed and predicted data
    freq_ind = 0
    axs = [ax1, ax2]
    temp_dobs = dobs_re[:, freq_ind].copy()
    ax1.plot(river_path[:, 0], river_path[:, 1], "k-", lw=0.5)
    inf = temp_dobs / abs(bp) * 1e6
    print(inf.min(), inf.max())
    out = utils.plot2Ddata(
        resolve["xy"][()],
        temp_dobs / abs(bp) * 1e6,
        ncontour=100,
        scale="log",
        dataloc=False,
        ax=ax1,
        contourOpts={"cmap": "viridis"},
    )
    vmin, vmax = out[0].get_clim()
    print(vmin, vmax)
    cb = plt.colorbar(
        out[0],
        ticks=np.logspace(np.log10(vmin), np.log10(vmax), 3),
        ax=ax1,
        format="%.1e",
        fraction=0.046,
        pad=0.04,
    )
    cb.set_label("Bz (ppm)")
    temp_dpred = dpred_re[:, freq_ind].copy()
    # temp_dpred[mask_:_data] = np.nan
    ax2.plot(river_path[:, 0], river_path[:, 1], "k-", lw=0.5)
    utils.plot2Ddata(
        resolve["xy"][()],
        temp_dpred / abs(bp) * 1e6,
        ncontour=100,
        scale="log",
        dataloc=False,
        contourOpts={
            "vmin": vmin,
            "vmax": vmax,
            "cmap": "viridis"
        },
        ax=ax2,
    )
    cb = plt.colorbar(
        out[0],
        ticks=np.logspace(np.log10(vmin), np.log10(vmax), 3),
        ax=ax2,
        format="%.1e",
        fraction=0.046,
        pad=0.04,
    )
    cb.set_label("Bz (ppm)")

    for i, ax in enumerate([ax0, ax1, ax2]):
        xticks = [460000, 463000]
        yticks = [6195000, 6198000, 6201000]
        xloc, yloc = 462100.0, 6196500.0
        ax.set_xticks(xticks)
        ax.set_yticks(yticks)
        # ax.plot(xloc, yloc, 'wo')
        ax.plot(river_path[:, 0], river_path[:, 1], "k", lw=0.5)

        ax.set_aspect("equal")
        ax.plot(resolve["xy"][:, 0],
                resolve["xy"][:, 1],
                "k.",
                alpha=0.02,
                ms=1)

        ax.set_yticklabels([str(f) for f in yticks])
        ax.set_ylabel("Northing (m)")
        ax.set_xlabel("Easting (m)")
        ax.set_title(title[i])

    plt.tight_layout()

    if plotIt:
        plt.show()

    if saveFig is True:
        fig.savefig("obspred_resolve.png", dpi=200)

    resolve.close()
    if cleanup:
        os.remove(downloads)
        shutil.rmtree(directory)
Exemple #21
0
def run(plotIt=True):

    # Create a mesh
    dx = 5.0

    hxind = [(dx, 5, -1.3), (dx, 15), (dx, 5, 1.3)]
    hyind = [(dx, 5, -1.3), (dx, 15), (dx, 5, 1.3)]
    hzind = [(dx, 5, -1.3), (dx, 7), (3.5, 1), (2, 5)]

    mesh = TensorMesh([hxind, hyind, hzind], "CCC")

    # Get index of the center
    midx = int(mesh.nCx / 2)
    midy = int(mesh.nCy / 2)

    # Lets create a simple Gaussian topo and set the active cells
    [xx, yy] = np.meshgrid(mesh.vectorNx, mesh.vectorNy)
    zz = -np.exp((xx ** 2 + yy ** 2) / 75 ** 2) + mesh.vectorNz[-1]

    # We would usually load a topofile
    topo = np.c_[utils.mkvc(xx), utils.mkvc(yy), utils.mkvc(zz)]

    # Go from topo to array of indices of active cells
    actv = utils.surface2ind_topo(mesh, topo, "N")
    actv = np.where(actv)[0]
    nC = len(actv)

    # Create and array of observation points
    xr = np.linspace(-30.0, 30.0, 20)
    yr = np.linspace(-30.0, 30.0, 20)
    X, Y = np.meshgrid(xr, yr)

    # Move the observation points 5m above the topo
    Z = -np.exp((X ** 2 + Y ** 2) / 75 ** 2) + mesh.vectorNz[-1] + 0.1

    # Create a GRAVsurvey
    rxLoc = np.c_[utils.mkvc(X.T), utils.mkvc(Y.T), utils.mkvc(Z.T)]
    rxLoc = gravity.receivers.Point(rxLoc)
    srcField = gravity.sources.SourceField([rxLoc])
    survey = gravity.survey.Survey(srcField)

    # We can now create a density model and generate data
    # Here a simple block in half-space
    model = np.zeros((mesh.nCx, mesh.nCy, mesh.nCz))
    model[(midx - 5) : (midx - 1), (midy - 2) : (midy + 2), -10:-6] = 0.75
    model[(midx + 1) : (midx + 5), (midy - 2) : (midy + 2), -10:-6] = -0.75
    model = utils.mkvc(model)
    model = model[actv]

    # Create active map to go from reduce set to full
    actvMap = maps.InjectActiveCells(mesh, actv, -100)

    # Create reduced identity map
    idenMap = maps.IdentityMap(nP=nC)

    # Create the forward simulation
    simulation = gravity.simulation.Simulation3DIntegral(
        survey=survey, mesh=mesh, rhoMap=idenMap, actInd=actv
    )

    # Compute linear forward operator and compute some data
    d = simulation.fields(model)

    # Add noise and uncertainties
    # We add some random Gaussian noise (1nT)
    synthetic_data = d + np.random.randn(len(d)) * 1e-3
    wd = np.ones(len(synthetic_data)) * 1e-3  # Assign flat uncertainties

    data_object = data.Data(survey, dobs=synthetic_data, noise_floor=wd)

    m0 = np.ones(nC) * 1e-4  # Starting model

    # Create sensitivity weights from our linear forward operator
    rxLoc = survey.source_field.receiver_list[0].locations

    # Create a regularization
    reg = regularization.Sparse(mesh, indActive=actv, mapping=idenMap)
    reg.norms = np.c_[0, 0, 0, 0]

    # Data misfit function
    dmis = data_misfit.L2DataMisfit(data=data_object, simulation=simulation)
    dmis.W = utils.sdiag(1 / wd)

    # Add directives to the inversion
    opt = optimization.ProjectedGNCG(
        maxIter=100, lower=-1.0, upper=1.0, maxIterLS=20, maxIterCG=10, tolCG=1e-3
    )
    invProb = inverse_problem.BaseInvProblem(dmis, reg, opt)
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1e-1)

    # Here is where the norms are applied
    # Use pick a threshold parameter empirically based on the distribution of
    # model parameters
    update_IRLS = directives.Update_IRLS(
        f_min_change=1e-4, max_irls_iterations=30, coolEpsFact=1.5, beta_tol=1e-2,
    )
    saveDict = directives.SaveOutputEveryIteration(save_txt=False)
    update_Jacobi = directives.UpdatePreconditioner()
    sensitivity_weights = directives.UpdateSensitivityWeights(everyIter=False)
    inv = inversion.BaseInversion(
        invProb,
        directiveList=[
            update_IRLS,
            sensitivity_weights,
            betaest,
            update_Jacobi,
            saveDict,
        ],
    )

    # Run the inversion

    mrec = inv.run(m0)

    if plotIt:
        # Here is the recovered susceptibility model
        ypanel = midx
        zpanel = -7
        m_l2 = actvMap * invProb.l2model
        m_l2[m_l2 == -100] = np.nan

        m_lp = actvMap * mrec
        m_lp[m_lp == -100] = np.nan

        m_true = actvMap * model
        m_true[m_true == -100] = np.nan

        vmin, vmax = mrec.min(), mrec.max()

        # Plot the data
        plot2Ddata(rxLoc, data_object.dobs)

        plt.figure()

        # Plot L2 model
        ax = plt.subplot(321)
        mesh.plotSlice(
            m_l2, ax=ax, normal="Z", ind=zpanel, grid=True, clim=(vmin, vmax)
        )
        plt.plot(
            ([mesh.vectorCCx[0], mesh.vectorCCx[-1]]),
            ([mesh.vectorCCy[ypanel], mesh.vectorCCy[ypanel]]),
            color="w",
        )
        plt.title("Plan l2-model.")
        plt.gca().set_aspect("equal")
        plt.ylabel("y")
        ax.xaxis.set_visible(False)
        plt.gca().set_aspect("equal", adjustable="box")

        # Vertical section
        ax = plt.subplot(322)
        mesh.plotSlice(m_l2, ax=ax, normal="Y", ind=midx, grid=True, clim=(vmin, vmax))
        plt.plot(
            ([mesh.vectorCCx[0], mesh.vectorCCx[-1]]),
            ([mesh.vectorCCz[zpanel], mesh.vectorCCz[zpanel]]),
            color="w",
        )
        plt.title("E-W l2-model.")
        plt.gca().set_aspect("equal")
        ax.xaxis.set_visible(False)
        plt.ylabel("z")
        plt.gca().set_aspect("equal", adjustable="box")

        # Plot Lp model
        ax = plt.subplot(323)
        mesh.plotSlice(
            m_lp, ax=ax, normal="Z", ind=zpanel, grid=True, clim=(vmin, vmax)
        )
        plt.plot(
            ([mesh.vectorCCx[0], mesh.vectorCCx[-1]]),
            ([mesh.vectorCCy[ypanel], mesh.vectorCCy[ypanel]]),
            color="w",
        )
        plt.title("Plan lp-model.")
        plt.gca().set_aspect("equal")
        ax.xaxis.set_visible(False)
        plt.ylabel("y")
        plt.gca().set_aspect("equal", adjustable="box")

        # Vertical section
        ax = plt.subplot(324)
        mesh.plotSlice(m_lp, ax=ax, normal="Y", ind=midx, grid=True, clim=(vmin, vmax))
        plt.plot(
            ([mesh.vectorCCx[0], mesh.vectorCCx[-1]]),
            ([mesh.vectorCCz[zpanel], mesh.vectorCCz[zpanel]]),
            color="w",
        )
        plt.title("E-W lp-model.")
        plt.gca().set_aspect("equal")
        ax.xaxis.set_visible(False)
        plt.ylabel("z")
        plt.gca().set_aspect("equal", adjustable="box")

        # Plot True model
        ax = plt.subplot(325)
        mesh.plotSlice(
            m_true, ax=ax, normal="Z", ind=zpanel, grid=True, clim=(vmin, vmax)
        )
        plt.plot(
            ([mesh.vectorCCx[0], mesh.vectorCCx[-1]]),
            ([mesh.vectorCCy[ypanel], mesh.vectorCCy[ypanel]]),
            color="w",
        )
        plt.title("Plan true model.")
        plt.gca().set_aspect("equal")
        plt.xlabel("x")
        plt.ylabel("y")
        plt.gca().set_aspect("equal", adjustable="box")

        # Vertical section
        ax = plt.subplot(326)
        mesh.plotSlice(
            m_true, ax=ax, normal="Y", ind=midx, grid=True, clim=(vmin, vmax)
        )
        plt.plot(
            ([mesh.vectorCCx[0], mesh.vectorCCx[-1]]),
            ([mesh.vectorCCz[zpanel], mesh.vectorCCz[zpanel]]),
            color="w",
        )
        plt.title("E-W true model.")
        plt.gca().set_aspect("equal")
        plt.xlabel("x")
        plt.ylabel("z")
        plt.gca().set_aspect("equal", adjustable="box")

        # Plot convergence curves
        fig, axs = plt.figure(), plt.subplot()
        axs.plot(saveDict.phi_d, "k", lw=2)
        axs.plot(
            np.r_[update_IRLS.iterStart, update_IRLS.iterStart],
            np.r_[0, np.max(saveDict.phi_d)],
            "k:",
        )

        twin = axs.twinx()
        twin.plot(saveDict.phi_m, "k--", lw=2)
        axs.text(
            update_IRLS.iterStart,
            np.max(saveDict.phi_d) / 2.0,
            "IRLS Steps",
            va="bottom",
            ha="center",
            rotation="vertical",
            size=12,
            bbox={"facecolor": "white"},
        )

        axs.set_ylabel("$\phi_d$", size=16, rotation=0)
        axs.set_xlabel("Iterations", size=14)
        twin.set_ylabel("$\phi_m$", size=16, rotation=0)
Exemple #22
0
    normal="Z",
    ind=int(-10),
    grid=True,
    pcolorOpts={"cmap": "Greys"},
    ax=ax[0],
)
mm = utils.plot2Ddata(
    data_grav.survey.receiver_locations,
    -data_grav.dobs,
    ax=ax[0],
    level=True,
    nx=20,
    ny=20,
    dataloc=True,
    ncontour=12,
    shade=True,
    contourOpts={
        "cmap": "Blues_r",
        "alpha": 0.8
    },
    levelOpts={
        "colors": "k",
        "linewidths": 0.5,
        "linestyles": "dashed"
    },
)
ax[0].set_aspect(1)
ax[0].set_title(
    "Gravity data values and locations,\nwith mesh and geology overlays",
    fontsize=16)
plt.colorbar(mm[0], cax=ax[2], orientation="horizontal")
ax[2].set_aspect(0.05)
    actInd=ind_active,
    store_sensitivities="forward_only",
)

# Compute predicted data for a susceptibility model
dpred = simulation.dpred(model)

# Plot
fig = plt.figure(figsize=(6, 5))
v_max = np.max(np.abs(dpred))

ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.85])
plot2Ddata(
    receiver_list[0].locations,
    dpred,
    ax=ax1,
    ncontour=30,
    clim=(-v_max, v_max),
    contourOpts={"cmap": "bwr"},
)
ax1.set_title("TMI Anomaly")
ax1.set_xlabel("x (m)")
ax1.set_ylabel("y (m)")

ax2 = fig.add_axes([0.87, 0.1, 0.03, 0.85])
norm = mpl.colors.Normalize(vmin=-np.max(np.abs(dpred)),
                            vmax=np.max(np.abs(dpred)))
cbar = mpl.colorbar.ColorbarBase(ax2,
                                 norm=norm,
                                 orientation="vertical",
                                 cmap=mpl.cm.bwr)
cbar.set_label("$nT$", rotation=270, labelpad=15, size=12)