コード例 #1
0
ファイル: test.py プロジェクト: JKutt/PyDev
def run(plotIt=True, survey_type="dipole-dipole"):
    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    xmin, xmax = 0., 200.
    ymin, ymax = 0., 0.
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey = DC.Utils.gen_DCIPsurvey(endl,
                                     survey_type=survey_type,
                                     dim=2,
                                     a=10,
                                     b=10,
                                     n=10)
    survey.getABMN_locations()
    survey = IO.from_ambn_locations_to_survey(survey.a_locations,
                                              survey.b_locations,
                                              survey.m_locations,
                                              survey.n_locations,
                                              survey_type,
                                              data_dc_type='volt')

    # Obtain 2D TensorMesh
    mesh, actind = IO.set_mesh()
    topo, mesh1D = DC.Utils.genTopography(mesh, -10, 0, its=100)
    print(topo)
コード例 #2
0
    def setUp(self):
        self.plotIt = False
        np.random.seed(1)
        # Initiate I/O class for DC
        self.IO = DC.IO()
        # Obtain ABMN locations

        xmin, xmax = 0., 200.
        ymin, ymax = 0., 0.
        zmin, zmax = 0, 0
        self.endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
コード例 #3
0
def run(plotIt=True, survey_type="dipole-dipole", p=0., qx=2., qz=2.):
    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    xmin, xmax = 0., 200.
    ymin, ymax = 0., 0.
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey = DC.Utils.gen_DCIPsurvey(endl,
                                     survey_type=survey_type,
                                     dim=2,
                                     a=10,
                                     b=10,
                                     n=10)
    survey.getABMN_locations()
    survey = IO.from_ambn_locations_to_survey(survey.a_locations,
                                              survey.b_locations,
                                              survey.m_locations,
                                              survey.n_locations,
                                              survey_type,
                                              data_dc_type='volt')

    # Obtain 2D TensorMesh
    mesh, actind = IO.set_mesh()
    topo, mesh1D = DC.Utils.genTopography(mesh, -10, 0, its=100)
    actind = Utils.surface2ind_topo(mesh, np.c_[mesh1D.vectorCCx, topo])
    survey.drapeTopo(mesh, actind, option="top")

    # Build a conductivity model
    blk_inds_c = Utils.ModelBuilder.getIndicesSphere(np.r_[60., -25.], 12.5,
                                                     mesh.gridCC)
    blk_inds_r = Utils.ModelBuilder.getIndicesSphere(np.r_[140., -25.], 12.5,
                                                     mesh.gridCC)
    layer_inds = mesh.gridCC[:, 1] > -5.
    sigma = np.ones(mesh.nC) * 1. / 100.
    sigma[blk_inds_c] = 1. / 10.
    sigma[blk_inds_r] = 1. / 1000.
    sigma[~actind] = 1. / 1e8
    rho = 1. / sigma

    # Show the true conductivity model
    if plotIt:
        fig = plt.figure(figsize=(12, 3))
        ax = plt.subplot(111)
        temp = rho.copy()
        temp[~actind] = np.nan
        out = mesh.plotImage(temp,
                             grid=True,
                             ax=ax,
                             gridOpts={'alpha': 0.2},
                             clim=(10, 1000),
                             pcolorOpts={
                                 "cmap": "viridis",
                                 "norm": colors.LogNorm()
                             })
        ax.plot(survey.electrode_locations[:, 0],
                survey.electrode_locations[:, 1], 'k.')
        ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
        ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
        cb = plt.colorbar(out[0])
        cb.set_label("Resistivity (ohm-m)")
        ax.set_aspect('equal')
        plt.show()

    # Use Exponential Map: m = log(rho)
    actmap = Maps.InjectActiveCells(mesh,
                                    indActive=actind,
                                    valInactive=np.log(1e8))
    mapping = Maps.ExpMap(mesh) * actmap

    # Generate mtrue
    mtrue = np.log(rho[actind])

    # Generate 2.5D DC problem
    # "N" means potential is defined at nodes
    prb = DC.Problem2D_N(mesh,
                         rhoMap=mapping,
                         storeJ=True,
                         Solver=Solver,
                         verbose=True)
    # Pair problem with survey
    try:
        prb.pair(survey)
    except:
        survey.unpair()
        prb.pair(survey)

    # Make synthetic DC data with 5% Gaussian noise
    dtrue = survey.makeSyntheticData(mtrue, std=0.05, force=True)

    IO.data_dc = dtrue
    # Show apparent resisitivty pseudo-section
    if plotIt:
        IO.plotPseudoSection(data=survey.dobs / IO.G,
                             data_type='apparent_resistivity')

    # Show apparent resisitivty histogram
    if plotIt:
        fig = plt.figure()
        out = hist(survey.dobs / IO.G, bins=20)
        plt.xlabel("Apparent Resisitivty ($\Omega$m)")
        plt.show()

    # Set initial model based upon histogram
    m0 = np.ones(actmap.nP) * np.log(100.)

    # Set uncertainty
    # floor
    eps = 10**(-3.2)
    # percentage
    std = 0.05
    dmisfit = DataMisfit.l2_DataMisfit(survey)
    uncert = abs(survey.dobs) * std + eps
    dmisfit.W = 1. / uncert

    # Map for a regularization
    regmap = Maps.IdentityMap(nP=int(actind.sum()))

    # Related to inversion
    reg = Regularization.Sparse(mesh,
                                indActive=actind,
                                mapping=regmap,
                                gradientType='components')
    #     gradientType = 'components'
    reg.norms = np.c_[p, qx, qz, 0.]
    IRLS = Directives.Update_IRLS(maxIRLSiter=20,
                                  minGNiter=1,
                                  betaSearch=False,
                                  fix_Jmatrix=True)

    opt = Optimization.InexactGaussNewton(maxIter=40)
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)
    beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2)
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0)
    target = Directives.TargetMisfit()
    update_Jacobi = Directives.UpdatePreconditioner()
    inv = Inversion.BaseInversion(invProb, directiveList=[betaest, IRLS])
    prb.counter = opt.counter = Utils.Counter()
    opt.LSshorten = 0.5
    opt.remember('xc')

    # Run inversion
    mopt = inv.run(m0)

    rho_est = mapping * mopt
    rho_est_l2 = mapping * invProb.l2model
    rho_est[~actind] = np.nan
    rho_est_l2[~actind] = np.nan
    rho_true = rho.copy()
    rho_true[~actind] = np.nan

    # show recovered conductivity
    if plotIt:
        vmin, vmax = rho.min(), rho.max()
        fig, ax = plt.subplots(3, 1, figsize=(20, 9))
        out1 = mesh.plotImage(rho_true,
                              clim=(10, 1000),
                              pcolorOpts={
                                  "cmap": "viridis",
                                  "norm": colors.LogNorm()
                              },
                              ax=ax[0])
        out2 = mesh.plotImage(rho_est_l2,
                              clim=(10, 1000),
                              pcolorOpts={
                                  "cmap": "viridis",
                                  "norm": colors.LogNorm()
                              },
                              ax=ax[1])
        out3 = mesh.plotImage(rho_est,
                              clim=(10, 1000),
                              pcolorOpts={
                                  "cmap": "viridis",
                                  "norm": colors.LogNorm()
                              },
                              ax=ax[2])

        out = [out1, out2, out3]
        titles = ["True", "L2", ("L%d, Lx%d, Lz%d") % (p, qx, qz)]
        for i in range(3):
            ax[i].plot(survey.electrode_locations[:, 0],
                       survey.electrode_locations[:, 1], 'kv')
            ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
            ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
            cb = plt.colorbar(out[i][0], ax=ax[i])
            cb.set_label("Resistivity ($\Omega$m)")
            ax[i].set_xlabel("Northing (m)")
            ax[i].set_ylabel("Elevation (m)")
            ax[i].set_aspect('equal')
            ax[i].set_title(titles[i])
        plt.tight_layout()
        plt.show()
コード例 #4
0
def run(plotIt=True, survey_type="dipole-dipole"):
    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    xmin, xmax = 0., 200.
    ymin, ymax = 0., 0.
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey_dc = DC.Utils.gen_DCIPsurvey(endl,
                                        survey_type=survey_type,
                                        dim=2,
                                        a=10,
                                        b=10,
                                        n=10)
    survey_dc.getABMN_locations()
    survey_dc = IO.from_ambn_locations_to_survey(survey_dc.a_locations,
                                                 survey_dc.b_locations,
                                                 survey_dc.m_locations,
                                                 survey_dc.n_locations,
                                                 survey_type,
                                                 data_dc_type='volt',
                                                 data_ip_type='volt')

    # Obtain 2D TensorMesh
    mesh, actind = IO.set_mesh()
    topo, mesh1D = DC.Utils.genTopography(mesh, -10, 0, its=100)
    actind = Utils.surface2ind_topo(mesh, np.c_[mesh1D.vectorCCx, topo])
    survey_dc.drapeTopo(mesh, actind, option="top")

    # Build conductivity and chargeability model
    blk_inds_c = Utils.ModelBuilder.getIndicesSphere(np.r_[60., -25.], 12.5,
                                                     mesh.gridCC)
    blk_inds_r = Utils.ModelBuilder.getIndicesSphere(np.r_[140., -25.], 12.5,
                                                     mesh.gridCC)
    blk_inds_charg = Utils.ModelBuilder.getIndicesSphere(
        np.r_[100., -25], 12.5, mesh.gridCC)
    sigma = np.ones(mesh.nC) * 1. / 100.
    sigma[blk_inds_c] = 1. / 10.
    sigma[blk_inds_r] = 1. / 1000.
    sigma[~actind] = 1. / 1e8
    rho = 1. / sigma
    charg = np.zeros(mesh.nC)
    charg[blk_inds_charg] = 0.1

    # Show the true conductivity model
    if plotIt:
        fig, axs = plt.subplots(2, 1, figsize=(12, 6))
        temp_rho = rho.copy()
        temp_rho[~actind] = np.nan
        temp_charg = charg.copy()
        temp_charg[~actind] = np.nan

        out1 = mesh.plotImage(temp_rho,
                              grid=True,
                              ax=axs[0],
                              gridOpts={'alpha': 0.2},
                              clim=(10, 1000),
                              pcolorOpts={
                                  "cmap": "viridis",
                                  "norm": colors.LogNorm()
                              })
        out2 = mesh.plotImage(temp_charg,
                              grid=True,
                              ax=axs[1],
                              gridOpts={'alpha': 0.2},
                              clim=(0, 0.1),
                              pcolorOpts={"cmap": "magma"})
        for i in range(2):
            axs[i].plot(survey_dc.electrode_locations[:, 0],
                        survey_dc.electrode_locations[:, 1], 'kv')
            axs[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
            axs[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
            axs[i].set_aspect('equal')
        cb = plt.colorbar(out1[0], ax=axs[0])
        cb.set_label("Resistivity (ohm-m)")
        cb = plt.colorbar(out2[0], ax=axs[1])
        cb.set_label("Chargeability")

        plt.show()

    # Use Exponential Map: m = log(rho)
    actmap = Maps.InjectActiveCells(mesh,
                                    indActive=actind,
                                    valInactive=np.log(1e8))
    mapping = Maps.ExpMap(mesh) * actmap

    # Generate mtrue_dc for resistivity
    mtrue_dc = np.log(rho[actind])

    # Generate 2.5D DC problem
    # "N" means potential is defined at nodes
    prb = DC.Problem2D_N(mesh, rhoMap=mapping, storeJ=True, Solver=Solver)
    # Pair problem with survey
    try:
        prb.pair(survey_dc)
    except:
        survey_dc.unpair()
        prb.pair(survey_dc)

    # Make synthetic DC data with 5% Gaussian noise
    dtrue_dc = survey_dc.makeSyntheticData(mtrue_dc, std=0.05, force=True)
    IO.data_dc = dtrue_dc

    # Generate mtrue_ip for chargability
    mtrue_ip = charg[actind]
    # Generate 2.5D DC problem
    # "N" means potential is defined at nodes
    prb_ip = IP.Problem2D_N(mesh,
                            etaMap=actmap,
                            storeJ=True,
                            rho=rho,
                            Solver=Solver)
    survey_ip = IP.from_dc_to_ip_survey(survey_dc, dim="2.5D")
    prb_ip.pair(survey_ip)

    dtrue_ip = survey_ip.makeSyntheticData(mtrue_ip, std=0.05)

    IO.data_ip = dtrue_ip

    # Show apparent resisitivty pseudo-section
    if plotIt:
        IO.plotPseudoSection(data_type='apparent_resistivity',
                             scale='log',
                             cmap='viridis')
        plt.show()

    # Show apparent chargeability pseudo-section
    if plotIt:
        IO.plotPseudoSection(data_type='apparent_chargeability',
                             scale='linear',
                             cmap='magma')
        plt.show()

    # Show apparent resisitivty histogram
    if plotIt:
        fig = plt.figure(figsize=(10, 4))
        ax1 = plt.subplot(121)
        out = hist(np.log10(abs(IO.voltages)), bins=20)
        ax1.set_xlabel("log10 DC voltage (V)")
        ax2 = plt.subplot(122)
        out = hist(IO.apparent_resistivity, bins=20)
        ax2.set_xlabel("Apparent Resistivity ($\Omega$m)")
        plt.tight_layout()
        plt.show()

    # Set initial model based upon histogram
    m0_dc = np.ones(actmap.nP) * np.log(100.)
    # Set uncertainty
    # floor
    eps_dc = 10**(-3.2)
    # percentage
    std_dc = 0.05

    mopt_dc, pred_dc = DC.run_inversion(m0_dc,
                                        survey_dc,
                                        actind,
                                        mesh,
                                        std_dc,
                                        eps_dc,
                                        beta0_ratio=1e0,
                                        use_sensitivity_weight=True)

    # Convert obtained inversion model to resistivity
    # rho = M(m), where M(.) is a mapping

    rho_est = mapping * mopt_dc
    rho_est[~actind] = np.nan
    rho_true = rho.copy()
    rho_true[~actind] = np.nan

    # show recovered conductivity
    if plotIt:
        vmin, vmax = rho.min(), rho.max()
        fig, ax = plt.subplots(2, 1, figsize=(20, 6))
        out1 = mesh.plotImage(rho_true,
                              clim=(10, 1000),
                              pcolorOpts={
                                  "cmap": "viridis",
                                  "norm": colors.LogNorm()
                              },
                              ax=ax[0])
        out2 = mesh.plotImage(rho_est,
                              clim=(10, 1000),
                              pcolorOpts={
                                  "cmap": "viridis",
                                  "norm": colors.LogNorm()
                              },
                              ax=ax[1])
        out = [out1, out2]
        for i in range(2):
            ax[i].plot(survey_dc.electrode_locations[:, 0],
                       survey_dc.electrode_locations[:, 1], 'kv')
            ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
            ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
            cb = plt.colorbar(out[i][0], ax=ax[i])
            cb.set_label("Resistivity ($\Omega$m)")
            ax[i].set_xlabel("Northing (m)")
            ax[i].set_ylabel("Elevation (m)")
            ax[i].set_aspect('equal')
        plt.tight_layout()
        plt.show()

    # Show apparent resisitivty histogram
    if plotIt:
        fig = plt.figure(figsize=(10, 4))
        ax1 = plt.subplot(121)
        out = hist(np.log10(abs(IO.voltages_ip)), bins=20)
        ax1.set_xlabel("log10 IP voltage (V)")
        ax2 = plt.subplot(122)
        out = hist(IO.apparent_chargeability, bins=20)
        ax2.set_xlabel("Apparent Chargeability (V/V)")
        plt.tight_layout()
        plt.show()

    # Set initial model based upon histogram
    m0_ip = np.ones(actmap.nP) * 1e-10
    # Set uncertainty
    # floor
    eps_ip = 10**(-4)
    # percentage
    std_ip = 0.05
    # Clean sensitivity function formed with true resistivity
    prb_ip._Jmatrix = None
    # Input obtained resistivity to form sensitivity
    prb_ip.rho = mapping * mopt_dc
    mopt_ip, _ = IP.run_inversion(m0_ip,
                                  survey_ip,
                                  actind,
                                  mesh,
                                  std_ip,
                                  eps_ip,
                                  upper=np.Inf,
                                  lower=0.,
                                  beta0_ratio=1e0,
                                  use_sensitivity_weight=True)

    # Convert obtained inversion model to chargeability
    # charg = M(m), where M(.) is a mapping for cells below topography

    charg_est = actmap * mopt_ip
    charg_est[~actind] = np.nan
    charg_true = charg.copy()
    charg_true[~actind] = np.nan

    # show recovered chargeability
    if plotIt:
        fig, ax = plt.subplots(2, 1, figsize=(20, 6))
        out1 = mesh.plotImage(charg_true,
                              clim=(0, 0.1),
                              pcolorOpts={"cmap": "magma"},
                              ax=ax[0])
        out2 = mesh.plotImage(charg_est,
                              clim=(0, 0.1),
                              pcolorOpts={"cmap": "magma"},
                              ax=ax[1])
        out = [out1, out2]
        for i in range(2):
            ax[i].plot(survey_dc.electrode_locations[:, 0],
                       survey_dc.electrode_locations[:, 1], 'rv')
            ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
            ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
            cb = plt.colorbar(out[i][0], ax=ax[i])
            cb.set_label("Resistivity ($\Omega$m)")
            ax[i].set_xlabel("Northing (m)")
            ax[i].set_ylabel("Elevation (m)")
            ax[i].set_aspect('equal')
        plt.tight_layout()
        plt.show()
コード例 #5
0
def run(plotIt=True,
        survey_type="dipole-dipole",
        rho_background=1e3,
        rho_block=1e2,
        block_x0=100,
        block_dx=10,
        block_y0=-10,
        block_dy=5):

    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    xmin, xmax = 0., 200.
    ymin, ymax = 0., 0.
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey = DC.Utils.gen_DCIPsurvey(endl,
                                     survey_type=survey_type,
                                     dim=2,
                                     a=10,
                                     b=10,
                                     n=10)
    survey.getABMN_locations()
    survey = IO.from_ambn_locations_to_survey(survey.a_locations,
                                              survey.b_locations,
                                              survey.m_locations,
                                              survey.n_locations,
                                              survey_type,
                                              data_dc_type='volt')

    # Obtain 2D TensorMesh
    mesh, actind = IO.set_mesh()
    # Flat topography
    actind = Utils.surface2ind_topo(mesh, np.c_[mesh.vectorCCx,
                                                mesh.vectorCCx * 0.])
    survey.drapeTopo(mesh, actind, option="top")
    # Use Exponential Map: m = log(rho)
    actmap = Maps.InjectActiveCells(mesh,
                                    indActive=actind,
                                    valInactive=np.log(1e8))
    parametric_block = Maps.ParametricBlock(mesh, slopeFact=1e2)
    mapping = Maps.ExpMap(mesh) * parametric_block
    # Set true model
    # val_background,val_block, block_x0, block_dx, block_y0, block_dy
    mtrue = np.r_[np.log(1e3), np.log(10), 100, 10, -20, 10]

    # Set initial model
    m0 = np.r_[np.log(rho_background),
               np.log(rho_block), block_x0, block_dx, block_y0, block_dy]
    rho = mapping * mtrue
    rho0 = mapping * m0
    # Show the true conductivity model
    fig = plt.figure(figsize=(12, 3))
    ax = plt.subplot(111)
    temp = rho.copy()
    temp[~actind] = np.nan
    out = mesh.plotImage(temp,
                         grid=False,
                         ax=ax,
                         gridOpts={'alpha': 0.2},
                         clim=(10, 1000),
                         pcolorOpts={
                             "cmap": "viridis",
                             "norm": colors.LogNorm()
                         })
    ax.plot(survey.electrode_locations[:, 0], survey.electrode_locations[:, 1],
            'k.')
    ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
    ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
    cb = plt.colorbar(out[0])
    cb.set_label("Resistivity (ohm-m)")
    ax.set_aspect('equal')
    ax.set_title("True resistivity model")
    plt.show()
    # Show the true conductivity model
    fig = plt.figure(figsize=(12, 3))
    ax = plt.subplot(111)
    temp = rho0.copy()
    temp[~actind] = np.nan
    out = mesh.plotImage(temp,
                         grid=False,
                         ax=ax,
                         gridOpts={'alpha': 0.2},
                         clim=(10, 1000),
                         pcolorOpts={
                             "cmap": "viridis",
                             "norm": colors.LogNorm()
                         })
    ax.plot(survey.electrode_locations[:, 0], survey.electrode_locations[:, 1],
            'k.')
    ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
    ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
    cb = plt.colorbar(out[0])
    cb.set_label("Resistivity (ohm-m)")
    ax.set_aspect('equal')
    ax.set_title("Initial resistivity model")
    plt.show()

    # Generate 2.5D DC problem
    # "N" means potential is defined at nodes
    prb = DC.Problem2D_N(mesh, rhoMap=mapping, storeJ=True, Solver=Solver)
    # Pair problem with survey
    try:
        prb.pair(survey)
    except:
        survey.unpair()
        prb.pair(survey)

    # Make synthetic DC data with 5% Gaussian noise
    dtrue = survey.makeSyntheticData(mtrue, std=0.05, force=True)

    # Show apparent resisitivty pseudo-section
    IO.plotPseudoSection(data=survey.dobs / IO.G,
                         data_type='apparent_resistivity')

    # Show apparent resisitivty histogram
    fig = plt.figure()
    out = hist(survey.dobs / IO.G, bins=20)
    plt.show()
    # Set uncertainty
    # floor
    eps = 10**(-3.2)
    # percentage
    std = 0.05
    dmisfit = DataMisfit.l2_DataMisfit(survey)
    uncert = abs(survey.dobs) * std + eps
    dmisfit.W = 1. / uncert

    # Map for a regularization
    mesh_1d = Mesh.TensorMesh([parametric_block.nP])
    # Related to inversion
    reg = Regularization.Simple(mesh_1d, alpha_x=0.)
    opt = Optimization.InexactGaussNewton(maxIter=10)
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)
    beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2)
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0)
    target = Directives.TargetMisfit()
    updateSensW = Directives.UpdateSensitivityWeights()
    update_Jacobi = Directives.UpdatePreconditioner()
    invProb.beta = 0.
    inv = Inversion.BaseInversion(invProb, directiveList=[target])
    prb.counter = opt.counter = Utils.Counter()
    opt.LSshorten = 0.5
    opt.remember('xc')

    # Run inversion
    mopt = inv.run(m0)

    # Convert obtained inversion model to resistivity
    # rho = M(m), where M(.) is a mapping

    rho_est = mapping * mopt
    rho_true = rho.copy()
    # show recovered conductivity
    vmin, vmax = rho.min(), rho.max()
    fig, ax = plt.subplots(2, 1, figsize=(20, 6))
    out1 = mesh.plotImage(rho_true,
                          clim=(10, 1000),
                          pcolorOpts={
                              "cmap": "viridis",
                              "norm": colors.LogNorm()
                          },
                          ax=ax[0])
    out2 = mesh.plotImage(rho_est,
                          clim=(10, 1000),
                          pcolorOpts={
                              "cmap": "viridis",
                              "norm": colors.LogNorm()
                          },
                          ax=ax[1])
    out = [out1, out2]
    for i in range(2):
        ax[i].plot(survey.electrode_locations[:, 0],
                   survey.electrode_locations[:, 1], 'kv')
        ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
        ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
        cb = plt.colorbar(out[i][0], ax=ax[i])
        cb.set_label("Resistivity ($\Omega$m)")
        ax[i].set_xlabel("Northing (m)")
        ax[i].set_ylabel("Elevation (m)")
        ax[i].set_aspect('equal')
    ax[0].set_title("True resistivity model")
    ax[1].set_title("Recovered resistivity model")
    plt.tight_layout()
    plt.show()
コード例 #6
0
ファイル: fm3d.py プロジェクト: JKutt/PyDev
def run(plotIt=True, survey_type="pole-dipole"):
    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    fileName1 = "C:/Users/johnk/Projects/Seabridge/fmdataDC.con"   # output mod
    fileName1_ = "C:/Users/johnk/Projects/Seabridge/fmdataIP.chg"  # output mod
    fileName2 = "C:/Users/johnk/Projects/Seabridge/forwardmodel.msh"  # in mesh
    mesh = Mesh.TensorMesh._readUBC_3DMesh(fileName2)     # Read in/create mesh

    print("Starting forward modeling")
    start = clock()
    # Define model Background
    rx = getRxData()                                     # rx locations
    tx = getTxData()                                     # tx locations
    survey_dc = generateSurvey(rx, tx, 45, 65)         # create survey object
    survey_dc.getABMN_locations()                           # get locations
    # survey_dc = IO.from_ambn_locations_to_survey(
    #     survey_dc.a_locations, survey_dc.b_locations,
    #     survey_dc.m_locations, survey_dc.n_locations,
    #     survey_type, data_dc_type='volt', data_ip_type='volt'
    # )
    uniq = Utils.uniqueRows(np.vstack((survey_dc.a_locations,
                                       survey_dc.b_locations,
                                       survey_dc.m_locations,
                                       survey_dc.n_locations)))
    electrode_locations = uniq[0]                            # assign
    actinds = Utils.surface2ind_topo(mesh,
                                     electrode_locations,
                                     method='cubic')      # active indicies
    survey_dc.drapeTopo(mesh, actinds)                       # drape topo
# =============================================================================
    # create sphere for ice representation
    x0 = (np.max(mesh.gridCC[:, 0]) +
          np.min(mesh.gridCC[:, 0])) / 2. + 50      # x0 center point of sphere
    y0 = (np.max(mesh.gridCC[:, 1]) +
          np.min(mesh.gridCC[:, 1])) / 2. - 50      # y0 center point of sphere
    z0 = 2350                                       # x0 center point of sphere
    # (np.max(mesh.gridCC[:, 2]) + np.min(mesh.gridCC[:, 2])) / 2.
    r0 = 500                                           # radius of sphere
    print(x0, y0, z0)
    csph = (np.sqrt((mesh.gridCC[:, 0] - x0)**2. +
                    (mesh.gridCC[:, 1] - y0)**2. +
                    (mesh.gridCC[:, 2] - z0)**2.)) < r0  # indicies of sphere
# sphere done =================================================================

# ============================================================================
# Create model
    mx = np.ones(mesh.nC) * 0.020                         # chargeability
    sigma = np.ones(mesh.nC) * 1. / 15000.

# create dipping structure parameters
    theta = 45. * np.pi / 180.                            # dipping angle
    x0_d = 374700.
    x1_d = 375000.
    y0_d = 6275850.
    y0_1d = 500. * np.sin(theta) + y0_d
    y1_d = 6275900.
    y1_1d = 500. * np.sin(theta) + y1_d
    z0_d = 1860.
    z1_d = z0_d - (500. * np.cos(theta))
    m_ = (z0_d - z1_d) / (y0_1d - y0_d)                   # slope of dip

    # loop through mesh and assign dipping structure conductivity
    for idx in range(mesh.nC):
        if z1_d <= mesh.gridCC[idx, 2] <= z0_d:
            if (x0_d <= mesh.gridCC[idx, 0] <= x1_d):
                yslope1 = y0_d + (1. / m_) * (mesh.gridCC[idx, 2] - z0_d)
                yslope2 = y1_d + (1. / m_) * (mesh.gridCC[idx, 2] - z0_d)
                if yslope1 <= mesh.gridCC[idx, 1] <= yslope2:
                    mx[idx] = 0.03
                    sigma[idx] = 1. / 300.

    # mx[csph] = ((0.025) *
    #             np.ones_like(mx[csph]))             # set sphere values
    mx[~actinds] = 1. / 1e8                             # flag air values
    # sigma[csph] = ((5000.) *
    #                np.ones_like(sigma[csph]))             # set sphere values
    sigma[~actinds] = 1. / 1e8                              # flag air values
    rho = 1. / sigma
    stop = clock()
    print(stop)
    # plot results
    # Show the true conductivity model
    if plotIt:
        ncy = mesh.nCy
        ncz = mesh.nCz
        ncx = mesh.nCx
        mtrue = mx
        print(mtrue.min(), mtrue.max())
        clim = [0, 0.04]
        fig, ax = plt.subplots(2, 2, figsize=(12, 6))
        ax = Utils.mkvc(ax)
        dat = mesh.plotSlice(((mx)), ax=ax[0], normal='Z', clim=clim,
                             ind=int(ncz / 2), pcolorOpts={"cmap": "jet"})
        ax[0].plot(rx[:, 0], rx[:, 1], 'or')
        ax[0].plot(tx[:, 0], tx[:, 1], 'dk')
        mesh.plotSlice(((mx)), ax=ax[1], normal='Y', clim=clim,
                       ind=int(ncy / 2 + 2), pcolorOpts={"cmap": "jet"})
        mesh.plotSlice(((mx)), ax=ax[2], normal='X', clim=clim,
                       ind=int(ncx / 2 + 4), pcolorOpts={"cmap": "jet"})
        mesh.plotSlice(((mx)), ax=ax[3], normal='X', clim=clim,
                       ind=int(ncx / 2 + 8), pcolorOpts={"cmap": "jet"})
        cbar_ax = fig.add_axes([0.82, 0.15, 0.05, 0.7])
        cb = plt.colorbar(dat[0], ax=cbar_ax)
        fig.subplots_adjust(right=0.85)
        cb.set_label('V/V')
        cbar_ax.axis('off')
        plt.show()

        mtrue = 1. / sigma
        print(mtrue.min(), mtrue.max())
        clim = [0, 20000]
        fig, ax = plt.subplots(2, 2, figsize=(12, 6))
        ax = Utils.mkvc(ax)
        dat = mesh.plotSlice(((mtrue)), ax=ax[0], normal='Z', clim=clim,
                             ind=int(ncz / 2 - 4), pcolorOpts={"cmap": "jet"})
        ax[0].plot(rx[:, 0], rx[:, 1], 'or')
        ax[0].plot(tx[:, 0], tx[:, 1], 'dk')
        mesh.plotSlice(((mtrue)), ax=ax[1], normal='Y', clim=clim,
                       ind=int(ncy / 2), pcolorOpts={"cmap": "jet"})
        mesh.plotSlice(((mtrue)), ax=ax[2], normal='X', clim=clim,
                       ind=int(ncx / 2 + 4), pcolorOpts={"cmap": "jet"})
        mesh.plotSlice(((mtrue)), ax=ax[3], normal='X', clim=clim,
                       ind=int(ncx / 2 + 8), pcolorOpts={"cmap": "jet"})
        cbar_ax = fig.add_axes([0.82, 0.15, 0.05, 0.7])
        cb = plt.colorbar(dat[0], ax=cbar_ax)
        fig.subplots_adjust(right=0.85)
        cb.set_label('rho')
        cbar_ax.axis('off')
        plt.show()

    # Use Exponential Map: m = log(rho)
    actmap = Maps.InjectActiveCells(
        mesh, indActive=actinds, valInactive=np.log(1e8)
    )
    mapping = Maps.ExpMap(mesh) * actmap

    # Generate mtrue_dc for resistivity
    mtrue_dc = np.log(rho[actinds])

    # Generate 3D DC problem
    # "CC" means potential is defined at center
    prb = DC.Problem3D_CC(
        mesh, rhoMap=mapping, storeJ=False,
        Solver=Solver
    )
    # Pair problem with survey
    try:
        prb.pair(survey_dc)
    except:
        survey_dc.unpair()
        prb.pair(survey_dc)

    # Make synthetic DC data with 5% Gaussian noise
    dtrue_dc = survey_dc.makeSyntheticData(mtrue_dc, std=0.05, force=True)
    IO.data_dc = dtrue_dc
    # Generate mtrue_ip for chargability
    mtrue_ip = mx[actinds]
    # Generate 3D DC problem
    # "CC" means potential is defined at center
    prb_ip = IP.Problem3D_CC(
        mesh, etaMap=actmap, storeJ=False, rho=rho,
        Solver=Solver
    )
    survey_ip = IP.from_dc_to_ip_survey(survey_dc, dim="3D")
    prb_ip.pair(survey_ip)
    dtrue_ip = survey_ip.makeSyntheticData(mtrue_ip, std=0.05)
    IO.data_ip = dtrue_ip

    # Show apparent resisitivty histogram
    # if plotIt:
    #     fig = plt.figure(figsize=(10, 4))
    #     ax1 = plt.subplot(121)
    #     out = hist(np.log10(abs(IO.voltages)), bins=20)
    #     ax1.set_xlabel("log10 DC voltage (V)")
    #     ax2 = plt.subplot(122)
    #     out = hist(IO.apparent_resistivity, bins=20)
    #     ax2.set_xlabel("Apparent Resistivity ($\Omega$m)")
    #     plt.tight_layout()
    #     plt.show()

    # Set initial model based upon histogram
    m0_dc = np.ones(actmap.nP) * np.log(10000.)
    # Set uncertainty
    # floor
    eps_dc = 10**(-3.2)
    # percentage
    std_dc = 0.05

    mopt_dc, pred_dc = DC.run_inversion(
        m0_dc, survey_dc, actinds, mesh, std_dc, eps_dc,
        use_sensitivity_weight=False)

    # Convert obtained inversion model to resistivity
    # rho = M(m), where M(.) is a mapping
    rho_est = mapping * mopt_dc
    # rho_est[~actinds] = np.nan
    rho_true = rho.copy()
    rho_true[~actinds] = np.nan

    # write data to file
    out_file = open(fileName1, "w")
    for i in range(rho_est.size):
        out_file.write("%0.5e\n" % rho_est[i])

    # Set initial model based upon histogram
    m0_ip = np.ones(actmap.nP) * 1e-10
    # Set uncertainty
    # floor
    eps_ip = 10**(-4)
    # percentage
    std_ip = 0.05
    # Clean sensitivity function formed with true resistivity
    prb_ip._Jmatrix = None
    # Input obtained resistivity to form sensitivity
    prb_ip.rho = mapping * mopt_dc
    mopt_ip, _ = IP.run_inversion(
        m0_ip, survey_ip, actinds, mesh, std_ip, eps_ip,
        upper=np.Inf, lower=0.,
        use_sensitivity_weight=False)

    # Convert obtained inversion model to chargeability
    # charg = M(m), where M(.) is a mapping for cells below topography
    charg_est = actmap * mopt_ip
    # charg_est[~actinds] = np.nan
    charg_true = charg.copy()
    charg_true[~actinds] = np.nan

    # write IP data to file
    out_file = open(fileName1_, "w")
    for i in range(charg_est.size):
        out_file.write("%0.5e\n" % charg_est[i])
コード例 #7
0
ファイル: fm3d.py プロジェクト: JKutt/PyDev
def run(plotIt=True, survey_type="pole-dipole"):
    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    fileName1 = "/Users/juan/Documents/testData/fmdata-daf.con"  # output mod
    fileName2 = "/Users/juan/Documents/testData/forwardmodel.msh"  # input mesh
    mesh = Mesh.TensorMesh._readUBC_3DMesh(fileName2)  # Read in/create mesh

    print("Starting forward modeling")
    start = clock()
    # Define model Background
    rx = getRxData()  # rx locations
    tx = getTxData()  # tx locations
    survey_dc = generateSurvey(rx, tx, 45, 55)  # create survey object
    survey_dc.survey_type = "pole-dipole"
    survey_dc.getABMN_locations()  # get locations
    # survey_dc = IO.from_ambn_locations_to_survey(
    #     survey_dc.a_locations, survey_dc.b_locations,
    #     survey_dc.m_locations, survey_dc.n_locations,
    #     survey_type, data_dc_type='volt', data_ip_type='volt'
    # )
    uniq = Utils.uniqueRows(
        np.vstack((survey_dc.a_locations, survey_dc.b_locations,
                   survey_dc.m_locations, survey_dc.n_locations)))
    electrode_locations = uniq[0]  # assign
    actinds = Utils.surface2ind_topo(mesh, electrode_locations,
                                     method='cubic')  # active indicies
    # survey_dc.drapeTopo(mesh, actinds)
    IO.a_locations = survey_dc.a_locations.copy()
    IO.b_locations = survey_dc.b_locations.copy()
    IO.m_locations = survey_dc.m_locations.copy()
    IO.n_locations = survey_dc.n_locations.copy()  # drape topo
    IO.data_dc_type = 'volt'
    IO.G = IO.geometric_factor(survey_dc)
    # =============================================================================
    # create sphere for ice representation
    x0 = (np.max(mesh.gridCC[:, 0]) +
          np.min(mesh.gridCC[:, 0])) / 2. + 50  # x0 center point of sphere
    y0 = (np.max(mesh.gridCC[:, 1]) +
          np.min(mesh.gridCC[:, 1])) / 2. - 50  # y0 center point of sphere
    z0 = 2350  # x0 center point of sphere
    # (np.max(mesh.gridCC[:, 2]) + np.min(mesh.gridCC[:, 2])) / 2.
    r0 = 500  # radius of sphere
    print(x0, y0, z0)
    csph = (np.sqrt((mesh.gridCC[:, 0] - x0)**2. +
                    (mesh.gridCC[:, 1] - y0)**2. +
                    (mesh.gridCC[:, 2] - z0)**2.)) < r0  # indicies of sphere
    # sphere done =================================================================
    # ============================================================================
    # Create model
    mx = np.ones(mesh.nC) * 0.018  # chargeability
    sigma = np.ones(mesh.nC) * 1. / 15000.

    # create dipping structure parameters
    theta = 45. * np.pi / 180.  # dipping angle
    x0_d = 374700.
    x1_d = 375000.
    y0_d = 6275850.
    y0_1d = 900. * np.sin(theta) + y0_d
    y1_d = 6275900.
    y1_1d = 900. * np.sin(theta) + y1_d
    z0_d = 1900.
    z1_d = z0_d - (900. * np.cos(theta))
    m_ = (z0_d - z1_d) / (y0_1d - y0_d)  # slope of dip

    # loop through mesh and assign dipping structure conductivity
    for idx in range(mesh.nC):
        if z1_d <= mesh.gridCC[idx, 2] <= z0_d:
            if (x0_d <= mesh.gridCC[idx, 0] <= x1_d):
                yslope1 = y0_d + (1. / m_) * (mesh.gridCC[idx, 2] - z0_d)
                yslope2 = y1_d + (1. / m_) * (mesh.gridCC[idx, 2] - z0_d)
                if yslope1 <= mesh.gridCC[idx, 1] <= yslope2:
                    mx[idx] = 0.035
                    sigma[idx] = 1. / 300.

    # mx[csph] = ((0.025) *
    #             np.ones_like(mx[csph]))             # set sphere values
    mx[~actinds] = 1. / 1e8  # flag air values
    # sigma[csph] = ((5000.) *
    #                np.ones_like(sigma[csph]))             # set sphere values
    sigma[~actinds] = 1. / 1e8  # flag air values
    rho = 1. / sigma
    stop = clock()
    print(stop)
    # plot results
    # Show the true conductivity model
    if plotIt:
        ncy = mesh.nCy
        ncz = mesh.nCz
        ncx = mesh.nCx
        print(mesh.nC)
        clim = [0, 0.04]
        fig, ax = plt.subplots(2, 2, figsize=(12, 6))
        ax = Utils.mkvc(ax)
        dat = mesh.plotSlice(((mx)),
                             ax=ax[0],
                             normal='Z',
                             clim=clim,
                             ind=int(ncz / 2 - 14),
                             pcolorOpts={"cmap": "jet"})
        ax[0].plot(rx[:, 0], rx[:, 1], 'or')
        ax[0].plot(tx[:, 0], tx[:, 1], 'dk')
        mesh.plotSlice(((mx)),
                       ax=ax[1],
                       normal='Y',
                       clim=clim,
                       ind=int(ncy / 2 + 2),
                       pcolorOpts={"cmap": "jet"})
        mesh.plotSlice(((mx)),
                       ax=ax[2],
                       normal='X',
                       clim=clim,
                       ind=int(ncx / 2 + 4),
                       pcolorOpts={"cmap": "jet"})
        mesh.plotSlice(((mx)),
                       ax=ax[3],
                       normal='X',
                       clim=clim,
                       ind=int(ncx / 2 + 8),
                       pcolorOpts={"cmap": "jet"})
        cbar_ax = fig.add_axes([0.82, 0.15, 0.05, 0.7])
        cb = plt.colorbar(dat[0], ax=cbar_ax)
        fig.subplots_adjust(right=0.85)
        cb.set_label('V/V')
        cbar_ax.axis('off')
        plt.show()
        # print(mtrue.min(), mtrue.max())
        # clim = [0, 20000]
        # fig, ax = plt.subplots(2, 2, figsize=(12, 6))
        # ax = Utils.mkvc(ax)
        # dat = mesh.plotSlice(((mtrue)), ax=ax[0], normal='Z', clim=clim,
        #                      ind=int(ncz / 2 - 4), pcolorOpts={"cmap": "jet"})
        # ax[0].plot(rx[:, 0], rx[:, 1], 'or')
        # mesh.plotSlice(((mtrue)), ax=ax[1], normal='Y', clim=clim,
        #                ind=int(ncy / 2), pcolorOpts={"cmap": "jet"})
        # mesh.plotSlice(((mtrue)), ax=ax[2], normal='X', clim=clim,
        #                ind=int(ncx / 2 + 4), pcolorOpts={"cmap": "jet"})
        # mesh.plotSlice(((mtrue)), ax=ax[3], normal='X', clim=clim,
        #                ind=int(ncx / 2 + 8), pcolorOpts={"cmap": "jet"})
        # cbar_ax = fig.add_axes([0.82, 0.15, 0.05, 0.7])
        # cb = plt.colorbar(dat[0], ax=cbar_ax)
        # fig.subplots_adjust(right=0.85)
        # cb.set_label('rho')
        # cbar_ax.axis('off')
        # plt.show()

    # print(error.size, survey_ip.obs.size)
    # error = np.asarray(survey_ip.dobs) * (np.random.randint(-1, 2, survey_ip.dobs) / 20.)
    # survey_ip.dobs = survey_ip.dobs + error
    # Use Exponential Map: m = log(rho)
    actmap = Maps.InjectActiveCells(mesh,
                                    indActive=actinds,
                                    valInactive=np.log(1e8))
    mapping = Maps.ExpMap(mesh) * actmap

    # Generate mtrue_dc for resistivity
    mtrue_dc = np.log(rho[actinds])

    # Generate 3D DC problem
    # "CC" means potential is defined at center
    prb = DC.Problem3D_CC(mesh, rhoMap=mapping, storeJ=False, Solver=Solver)
    # Pair problem with survey
    # try:
    prb.pair(survey_dc)
    # except:
    #     survey_dc.unpair()
    #     prb.pair(survey_dc)

    survey_dc.dpred(mtrue_dc)
    # Make synthetic DC data with 5% Gaussian noise
    dtrue_dc = survey_dc.makeSyntheticData(mtrue_dc, std=0.05, force=True)
    IO.data_dc = dtrue_dc
    # Generate mtrue_ip for chargability
    mtrue_ip = mx[actinds]
    # Generate 3D DC problem
    # "CC" means potential is defined at center
    prb_ip = IP.Problem3D_CC(mesh,
                             etaMap=actmap,
                             storeJ=False,
                             rho=rho,
                             Solver=Solver)
    survey_ip = IP.from_dc_to_ip_survey(survey_dc, dim="3D")
    survey_ip.survey_type = "pole-dipole"
    survey_ip.getABMN_locations()
    prb_ip.pair(survey_ip)
    survey_ip.dpred(mtrue_ip)
    dtrue_ip = survey_ip.makeSyntheticData(mtrue_ip, std=0.05)
    survey_ip.std = np.ones_like(dtrue_ip) * 0.05
    survey_ip.eps = np.ones_like(dtrue_ip) * 10**(-4)
    IO.data_ip = dtrue_ip
    DC.Utils.writeUBC_DCobs("fmip.obs", survey_ip, 3, 'GENERAL', 'pole-dipole')
コード例 #8
0
# Convert file to DC.IO object
# ----------------------------
#

# Number of the data
ndata = df[header_loc[0]].values.size
# ABMN locations
a = np.c_[df[header_loc[0]].values, np.zeros(ndata)]
b = np.c_[df[header_loc[1]].values, np.zeros(ndata)]
m = np.c_[df[header_loc[2]].values, np.zeros(ndata)]
n = np.c_[df[header_loc[3]].values, np.zeros(ndata)]
# Apparent resistivity
apprho = df[header_apprho].values

# Create DC.IO survey Object object
IO = DC.IO()
# Generate DC survey using IO object
dc_survey = IO.from_ambn_locations_to_survey(
    a,
    b,
    m,
    n,
    survey_type='dipole-dipole',
    data_dc=apprho,
    data_dc_type='apparent_resistivity')

###############################################################################
#
# Plot
# ----
#
コード例 #9
0
def run(plotIt=True, survey_type="dipole-dipole"):
    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    xmin, xmax = 0., 200.
    ymin, ymax = 0., 0.
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey = DC.Utils.gen_DCIPsurvey(endl, survey_type=survey_type, dim=2,
                                     a=10, b=10, n=10)
    survey.getABMN_locations()
    survey = IO.from_ambn_locations_to_survey(
        survey.a_locations, survey.b_locations,
        survey.m_locations, survey.n_locations,
        survey_type, data_dc_type='volt'
    )

    # Obtain 2D TensorMesh
    mesh, actind = IO.set_mesh()
    topo, mesh1D = DC.Utils.genTopography(mesh, -10, 0, its=100)
    actind = Utils.surface2ind_topo(mesh, np.c_[mesh1D.vectorCCx, topo])
    survey.drapeTopo(mesh, actind, option="top")

    # Build a conductivity model
    blk_inds_c = Utils.ModelBuilder.getIndicesSphere(
        np.r_[60., -25.], 12.5, mesh.gridCC
    )
    blk_inds_r = Utils.ModelBuilder.getIndicesSphere(
        np.r_[140., -25.], 12.5, mesh.gridCC
    )
    layer_inds = mesh.gridCC[:, 1] > -5.
    sigma = np.ones(mesh.nC)*1./100.
    sigma[blk_inds_c] = 1./10.
    sigma[blk_inds_r] = 1./1000.
    sigma[~actind] = 1./1e8
    rho = 1./sigma

    # Show the true conductivity model
    if plotIt:
        fig = plt.figure(figsize=(12, 3))
        ax = plt.subplot(111)
        temp = rho.copy()
        temp[~actind] = np.nan
        out = mesh.plotImage(
            temp, grid=True, ax=ax, gridOpts={'alpha': 0.2},
            clim=(10, 1000),
            pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()}
        )
        ax.plot(
            survey.electrode_locations[:, 0],
            survey.electrode_locations[:, 1], 'k.'
        )
        ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
        ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
        cb = plt.colorbar(out[0])
        cb.set_label("Resistivity (ohm-m)")
        ax.set_aspect('equal')
        plt.show()

    # Use Exponential Map: m = log(rho)
    actmap = Maps.InjectActiveCells(
        mesh, indActive=actind, valInactive=np.log(1e8)
    )
    mapping = Maps.ExpMap(mesh) * actmap

    # Generate mtrue
    mtrue = np.log(rho[actind])

    # Generate 2.5D DC problem
    # "N" means potential is defined at nodes
    prb = DC.Problem2D_N(
        mesh, rhoMap=mapping, storeJ=True,
        Solver=Solver
    )
    # Pair problem with survey
    try:
        prb.pair(survey)
    except:
        survey.unpair()
        prb.pair(survey)

    geometric_factor = survey.set_geometric_factor(
        data_type="apparent_resistivity",
        survey_type='dipole-dipole',
        space_type='half-space'
    )

    # Make synthetic DC data with 5% Gaussian noise
    dtrue = survey.makeSyntheticData(mtrue, std=0.05, force=True)

    IO.data_dc = dtrue
    # Show apparent resisitivty pseudo-section
    if plotIt:
        IO.plotPseudoSection(
            data=survey.dobs, data_type='apparent_resistivity'
        )

    # Show apparent resisitivty histogram
    if plotIt:
        fig = plt.figure()
        out = hist(survey.dobs, bins=20)
        plt.xlabel("Apparent Resisitivty ($\Omega$m)")
        plt.show()

    # Set initial model based upon histogram
    m0 = np.ones(actmap.nP)*np.log(100.)

    # Set uncertainty
    # floor (10 ohm-m)
    eps = 1.
    # percentage
    std = 0.05
    dmisfit = DataMisfit.l2_DataMisfit(survey)
    uncert = abs(survey.dobs) * std + eps
    dmisfit.W = 1./uncert

    # Map for a regularization
    regmap = Maps.IdentityMap(nP=int(actind.sum()))

    # Related to inversion
    reg = Regularization.Sparse(mesh, indActive=actind, mapping=regmap)
    opt = Optimization.InexactGaussNewton(maxIter=15)
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)
    beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2)
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0)
    target = Directives.TargetMisfit()
    updateSensW = Directives.UpdateSensitivityWeights()
    update_Jacobi = Directives.UpdatePreconditioner()
    inv = Inversion.BaseInversion(
        invProb, directiveList=[
            beta, betaest, target, updateSensW, update_Jacobi
        ]
        )
    prb.counter = opt.counter = Utils.Counter()
    opt.LSshorten = 0.5
    opt.remember('xc')

    # Run inversion
    mopt = inv.run(m0)

    # Get diag(JtJ)
    mask_inds = np.ones(mesh.nC, dtype=bool)
    jtj = np.sqrt(updateSensW.JtJdiag[0])
    jtj /= jtj.max()
    temp = np.ones_like(jtj, dtype=bool)
    temp[jtj > 0.005] = False
    mask_inds[actind] = temp
    actind_final = np.logical_and(actind, ~mask_inds)
    jtj_cc = np.ones(mesh.nC)*np.nan
    jtj_cc[actind] = jtj

    # Show the sensitivity
    if plotIt:
        fig = plt.figure(figsize=(12, 3))
        ax = plt.subplot(111)
        temp = rho.copy()
        temp[~actind] = np.nan
        out = mesh.plotImage(
            jtj_cc, grid=True, ax=ax,
            gridOpts={'alpha': 0.2}, clim=(0.005, 0.5),
            pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()}
        )
        ax.plot(
            survey.electrode_locations[:, 0],
            survey.electrode_locations[:, 1], 'k.'
        )
        ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
        ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
        cb = plt.colorbar(out[0])
        cb.set_label("Sensitivity")
        ax.set_aspect('equal')
        plt.show()

    # Convert obtained inversion model to resistivity
    # rho = M(m), where M(.) is a mapping

    rho_est = mapping*mopt
    rho_est[~actind_final] = np.nan
    rho_true = rho.copy()
    rho_true[~actind_final] = np.nan

    # show recovered conductivity
    if plotIt:
        vmin, vmax = rho.min(), rho.max()
        fig, ax = plt.subplots(2, 1, figsize=(20, 6))
        out1 = mesh.plotImage(
                rho_true, clim=(10, 1000),
                pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()},
                ax=ax[0]
        )
        out2 = mesh.plotImage(
            rho_est, clim=(10, 1000),
            pcolorOpts={"cmap": "viridis", "norm": colors.LogNorm()},
            ax=ax[1]
        )
        out = [out1, out2]
        for i in range(2):
            ax[i].plot(
                survey.electrode_locations[:, 0],
                survey.electrode_locations[:, 1], 'kv'
            )
            ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
            ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
            cb = plt.colorbar(out[i][0], ax=ax[i])
            cb.set_label("Resistivity ($\Omega$m)")
            ax[i].set_xlabel("Northing (m)")
            ax[i].set_ylabel("Elevation (m)")
            ax[i].set_aspect('equal')
        plt.tight_layout()
        plt.show()