Exemplo n.º 1
0
    def set_geometric_factor(
        self,
        space_type="half-space",
        data_type=None,
        survey_type=None,
    ):
        if data_type is not None:
            warnings.warn(
                "The data_type kwarg is deprecated, please set the data_type on the "
                "receiver object itself. This behavoir will be removed in SimPEG "
                "0.16.0",
                DeprecationWarning,
            )
        if survey_type is not None:
            warnings.warn(
                "The survey_type parameter is no longer needed, and it will be removed "
                "in SimPEG 0.15.0.")

        geometric_factor = static_utils.geometric_factor(self,
                                                         space_type=space_type)

        geometric_factor = data.Data(self, geometric_factor)
        for source in self.source_list:
            for rx in source.receiver_list:
                if data_type is not None:
                    rx.data_type = data_type
                if rx.data_type == "apparent_resistivity":
                    rx._geometric_factor[source] = geometric_factor[source, rx]
        return geometric_factor
Exemplo n.º 2
0
def read_gravity_3d_ubc(obs_file):
    """
    Read UBC grav file format

    INPUT:
    :param fileName, path to the UBC obs grav file
    :param ftype, 'dobs' 'dpred' 'survey'

    OUTPUT:
    :param survey

    """
    from SimPEG.potential_fields import gravity
    from SimPEG import data

    fid = open(obs_file, "r")

    # First line has the number of rows
    line = fid.readline()
    ndat = int(line.split()[0])

    # Pre-allocate space for obsx, obsy, obsz, data, uncert
    line = fid.readline()

    d = np.zeros(ndat, dtype=float)
    wd = np.zeros(ndat, dtype=float)
    locXYZ = np.zeros((ndat, 3), dtype=float)

    ii = 0
    while ii < ndat:

        temp = np.array(line.split(), dtype=float)
        if len(temp) > 0:
            locXYZ[ii, :] = temp[:3]
            if len(temp) > 3:
                d[ii] = temp[3]

                if len(temp) == 5:
                    wd[ii] = temp[4]

            ii += 1
        line = fid.readline()
    fid.close()

    if np.all(wd == 0.0):
        wd = None

    # UBC and SimPEG used opposite sign convention for
    # gravity data so must multiply by -1.
    if np.all(d == 0.0):
        d = None
    else:
        d *= -1.0

    rxLoc = gravity.receivers.Point(locXYZ)
    srcField = gravity.sources.SourceField([rxLoc])
    survey = gravity.survey.Survey(srcField)
    data_object = data.Data(survey, dobs=d, standard_deviation=wd)
    return data_object
Exemplo n.º 3
0
def readUBCmagneticsObservations(obs_file):
    """
        Read and write UBC mag file format

        INPUT:
        :param fileName, path to the UBC obs mag file

        OUTPUT:
        :param survey
        :param M, magnetization orentiaton (MI, MD)
    """
    from SimPEG.potential_fields import magnetics
    from SimPEG import data

    fid = open(obs_file, "r")

    # First line has the inclination,declination and amplitude of B0
    line = fid.readline()
    B = np.array(line.split(), dtype=float)

    # Second line has the magnetization orientation and a flag
    line = fid.readline()
    M = np.array(line.split(), dtype=float)

    # Third line has the number of rows
    line = fid.readline()
    ndat = int(line.strip())

    # Pre-allocate space for obsx, obsy, obsz, data, uncert
    line = fid.readline()
    temp = np.array(line.split(), dtype=float)

    d = np.zeros(ndat, dtype=float)
    wd = np.zeros(ndat, dtype=float)
    locXYZ = np.zeros((ndat, 3), dtype=float)

    ii = 0
    while ii < ndat:

        temp = np.array(line.split(), dtype=float)
        if len(temp) > 0:
            locXYZ[ii, :] = temp[:3]

            if len(temp) > 3:
                d[ii] = temp[3]

                if len(temp) == 5:
                    wd[ii] = temp[4]
            ii += 1
        line = fid.readline()
    fid.close()

    rxLoc = magnetics.receivers.Point(locXYZ)
    srcField = magnetics.sources.SourceField([rxLoc], parameters=(B[2], B[0], B[1]))
    survey = magnetics.survey.Survey(srcField)
    data_object = data.Data(survey, dobs=d, standard_deviation=wd)

    return data_object
Exemplo n.º 4
0
    def test_dcip3d(self):

        # Survey parameters
        data_type = "volt"
        end_points = np.array([-100, 50, 100, -50])

        # Create sources and data object
        source_list = []
        for stype in self.survey_type:
            source_list = source_list + utils.generate_dcip_sources_line(
                stype,
                data_type,
                "3D",
                end_points,
                self.topo,
                self.num_rx_per_src,
                self.station_spacing,
            )
        survey3D = dc.survey.Survey(source_list)
        dobs = np.random.rand(survey3D.nD)
        dunc = 1e-3 * np.ones(survey3D.nD)
        data3D = data.Data(survey3D, dobs=dobs, standard_deviation=dunc)

        # Write DCIP3D files
        io_utils.write_dcipoctree_ubc(
            self.dir_path + "/dcip3d_general.txt",
            data3D,
            "volt",
            "dobs",
            format_type="general",
            comment_lines="GENERAL FORMAT",
        )
        io_utils.write_dcipoctree_ubc(
            self.dir_path + "/dcip3d_surface.txt",
            data3D,
            "volt",
            "dobs",
            format_type="surface",
            comment_lines="SURFACE FORMAT",
        )

        # Read DCIP3D files
        data_general = io_utils.read_dcipoctree_ubc(
            self.dir_path + "/dcip3d_general.txt", "volt"
        )
        data_surface = io_utils.read_dcipoctree_ubc(
            self.dir_path + "/dcip3d_surface.txt", "volt"
        )

        # Compare
        passed = np.all(
            np.isclose(data3D.dobs, data_general.dobs)
            & np.isclose(data3D.dobs, data_surface.dobs)
        )

        self.assertTrue(passed)
        print("READ/WRITE METHODS FOR DCIP3D DATA PASSED!")
Exemplo n.º 5
0
    def test_ip2d(self):

        data_type = "apparent_chargeability"
        end_points = np.array([-100, 100])

        # Create sources and data object
        source_list = []
        for stype in self.survey_type:
            source_list = source_list + utils.generate_dcip_sources_line(
                stype,
                data_type,
                "2D",
                end_points,
                self.topo,
                self.num_rx_per_src,
                self.station_spacing,
            )
        survey2D = dc.survey.Survey(source_list)
        dobs = np.random.rand(survey2D.nD)
        dunc = 1e-3 * np.ones(survey2D.nD)
        data2D = data.Data(survey2D, dobs=dobs, standard_deviation=dunc)

        # Write DCIP2D files
        io_utils.write_dcip2d_ubc(
            self.dir_path + "/ip2d_general.txt",
            data2D,
            "apparent_chargeability",
            "dobs",
            "general",
            comment_lines="GENERAL FORMAT",
        )
        io_utils.write_dcip2d_ubc(
            self.dir_path + "/ip2d_surface.txt",
            data2D,
            "apparent_chargeability",
            "dobs",
            "surface",
            comment_lines="SURFACE FORMAT",
        )

        # Read DCIP2D files
        data_general = io_utils.read_dcip2d_ubc(
            self.dir_path + "/ip2d_general.txt", "apparent_chargeability", "general"
        )
        data_surface = io_utils.read_dcip2d_ubc(
            self.dir_path + "/ip2d_surface.txt", "apparent_chargeability", "surface"
        )

        # Compare
        passed = np.all(
            np.isclose(data2D.dobs, data_general.dobs)
            & np.isclose(data2D.dobs, data_surface.dobs)
        )

        self.assertTrue(passed)
        print("READ/WRITE METHODS FOR IP2D DATA PASSED!")
Exemplo n.º 6
0
    def test_data(self):
        V = []
        for src in self.D.survey.source_list:
            for rx in src.receiver_list:
                v = np.random.rand(rx.nD)
                V += [v]
                index = self.D.index_dictionary[src][rx]
                self.D.dobs[index] = v
        V = np.concatenate(V)
        self.assertTrue(np.all(V == self.D.dobs))

        D2 = data.Data(self.D.survey, V)
        self.assertTrue(np.all(D2.dobs == self.D.dobs))
Exemplo n.º 7
0
    def set_geometric_factor(
        self, data_type="volt", survey_type="dipole-dipole", space_type="half-space"
    ):

        geometric_factor = static_utils.geometric_factor(
            self, survey_type=survey_type, space_type=space_type
        )

        geometric_factor = data.Data(self, geometric_factor)
        for source in self.source_list:
            for rx in source.receiver_list:
                rx._geometric_factor = geometric_factor[source, rx]
                rx.data_type = data_type
        return geometric_factor
Exemplo n.º 8
0
    def test_standard_dev(self):
        V = []
        for src in self.D.survey.source_list:
            for rx in src.receiver_list:
                v = np.random.rand(rx.nD)
                V += [v]
                index = self.D.index_dictionary[src][rx]
                self.D.relative_error[index] = v
                self.assertTrue(np.all(v == self.D.relative_error[index]))
        V = np.concatenate(V)
        self.assertTrue(np.all(V == self.D.relative_error))

        D2 = data.Data(self.D.survey, relative_error=V)
        self.assertTrue(np.all(D2.relative_error == self.D.relative_error))
    def run_inversion_direct(
        self,
        m0=0.0,
        mref=0.0,
        percentage=0,
        floor=3e-2,
        chi_fact=1.0,
        beta_min=1e-4,
        beta_max=1e5,
        n_beta=81,
        alpha_s=1.0,
        alpha_x=0,
    ):

        self.uncertainty = percentage * abs(self.data_vec) * 0.01 + floor

        survey_obj, simulation_obj = self.get_problem_survey()
        data_obj = data.Data(survey_obj,
                             dobs=self.data_vec,
                             noise_floor=self.uncertainty)
        dmis = data_misfit.L2DataMisfit(simulation=simulation_obj,
                                        data=data_obj)

        m0 = np.ones(self.M) * m0
        mref = np.ones(self.M) * mref
        reg = regularization.Tikhonov(self.mesh_prop,
                                      alpha_s=alpha_s,
                                      alpha_x=alpha_x,
                                      mref=mref)

        betas = np.logspace(np.log10(beta_min), np.log10(beta_max),
                            n_beta)[::-1]

        phi_d = np.zeros(n_beta, dtype=float)
        phi_m = np.zeros(n_beta, dtype=float)
        models = []
        preds = []

        G = dmis.W.dot(self.G)

        for ii, beta in enumerate(betas):
            A = G.T.dot(G) + beta * reg.deriv2(m0)
            b = -(dmis.deriv(m0) + beta * reg.deriv(m0))
            m = np.linalg.solve(A, b)
            phi_d[ii] = dmis(m) * 2.0
            phi_m[ii] = reg(m) * 2.0
            models.append(m)
            preds.append(simulation_obj.dpred(m))

        return phi_d, phi_m, models, preds, betas
Exemplo n.º 10
0
def createMagSurvey(xyzd, B):
    """
        Create SimPEG magnetic survey pbject

        INPUT
        :param array: xyzd, n-by-4 array of observation points and data
        :param array: B, 1-by-3 array of inducing field param [|B|, Inc, Dec]
    """

    rxLoc = mag.receivers.Point(xyzd[:, :3])
    source_field = mag.sources.SourceField(receiver_list=[rxLoc], parameters=B)
    survey = mag.survey.MagneticSurvey(source_field)
    dobj = data.Data(survey, xyzd[:, 3])

    return survey, dobj
Exemplo n.º 11
0
    def setUp(self):
        mesh = discretize.TensorMesh([np.ones(n) * 5 for n in [10, 11, 12]],
                                     [0, 0, -30])
        x = np.linspace(5, 10, 3)
        XYZ = utils.ndgrid(x, x, np.r_[0.0])
        srcLoc = np.r_[0.0, 0.0, 0.0]
        receiver_list0 = survey.BaseRx(XYZ)
        Src0 = survey.BaseSrc([receiver_list0], location=srcLoc)

        receiver_list1 = survey.BaseRx(XYZ)
        Src1 = survey.BaseSrc([receiver_list1], location=srcLoc)

        receiver_list2 = survey.BaseRx(XYZ)
        Src2 = survey.BaseSrc([receiver_list2], location=srcLoc)

        receiver_list3 = survey.BaseRx(XYZ)
        Src3 = survey.BaseSrc([receiver_list3], location=srcLoc)
        Src4 = survey.BaseSrc(
            [receiver_list0, receiver_list1, receiver_list2, receiver_list3],
            location=srcLoc,
        )
        source_list = [Src0, Src1, Src2, Src3, Src4]

        mysurvey = survey.BaseSurvey(source_list=source_list)
        sim = simulation.BaseSimulation(mesh=mesh, survey=mysurvey)
        self.D = data.Data(mysurvey)
        self.F = fields.Fields(
            sim,
            knownFields={
                "phi": "CC",
                "e": "E",
                "b": "F"
            },
            dtype={
                "phi": float,
                "e": complex,
                "b": complex
            },
        )
        self.Src0 = Src0
        self.Src1 = Src1
        self.mesh = mesh
        self.XYZ = XYZ
        self.simulation = sim
Exemplo n.º 12
0
 def setUp(self):
     mesh = discretize.TensorMesh([np.ones(n) * 5 for n in [10, 11, 12]],
                                  [0, 0, -30])
     x = np.linspace(5, 10, 3)
     XYZ = utils.ndgrid(x, x, np.r_[0.0])
     srcLoc = np.r_[0, 0, 0.0]
     rxList0 = survey.BaseRx(XYZ)
     Src0 = survey.BaseSrc([rxList0], location=srcLoc)
     rxList1 = survey.BaseRx(XYZ)
     Src1 = survey.BaseSrc([rxList1], location=srcLoc)
     rxList2 = survey.BaseRx(XYZ)
     Src2 = survey.BaseSrc([rxList2], location=srcLoc)
     rxList3 = survey.BaseRx(XYZ)
     Src3 = survey.BaseSrc([rxList3], location=srcLoc)
     Src4 = survey.BaseSrc([rxList0, rxList1, rxList2, rxList3],
                           location=srcLoc)
     srcList = [Src0, Src1, Src2, Src3, Src4]
     mysurvey = survey.BaseSurvey(source_list=srcList)
     self.D = data.Data(mysurvey)
Exemplo n.º 13
0
def readUBCgravityObservations(obs_file):
    """
    Read UBC grav file format

    INPUT:
    :param fileName, path to the UBC obs grav file

    OUTPUT:
    :param survey

    """
    from SimPEG.potential_fields import gravity
    from SimPEG import data

    fid = open(obs_file, "r")

    # First line has the number of rows
    line = fid.readline()
    ndat = int(line.split()[0])

    # Pre-allocate space for obsx, obsy, obsz, data, uncert
    line = fid.readline()

    d = np.zeros(ndat, dtype=float)
    wd = np.zeros(ndat, dtype=float)
    locXYZ = np.zeros((ndat, 3), dtype=float)

    ii = 0
    while ii < ndat:
        temp = np.array(line.split(), dtype=float)
        if len(temp) > 0:
            locXYZ[ii, :] = temp[:3]
            d[ii] = temp[3]
            wd[ii] = temp[4]
            ii += 1
        line = fid.readline()
    fid.close()

    rxLoc = gravity.receivers.Point(locXYZ)
    srcField = gravity.sources.SourceField([rxLoc])
    survey = gravity.survey.Survey(srcField)
    data_object = data.Data(survey, dobs=d, standard_deviation=wd)
    return data_object
Exemplo n.º 14
0
    def test_dc2d(self):

        data_type = 'volt'
        end_points = np.array([-100, 100])

        # Create sources and data object
        source_list = []
        for stype in self.survey_type:
            source_list = source_list + utils.generate_dcip_sources_line(
                stype, data_type, '2D', end_points, self.topo,
                self.num_rx_per_src, self.station_spacing)
        survey2D = dc.survey.Survey(source_list)
        dobs = np.random.rand(survey2D.nD)
        dunc = 1e-3 * np.ones(survey2D.nD)
        data2D = data.Data(survey2D, dobs=dobs, standard_deviation=dunc)

        io_utils.write_dcip2d_ubc(self.dir_path + '/dc2d_general.txt',
                                  data2D,
                                  'volt',
                                  'dobs',
                                  'general',
                                  comment_lines="GENERAL FORMAT")
        io_utils.write_dcip2d_ubc(self.dir_path + '/dc2d_surface.txt',
                                  data2D,
                                  'volt',
                                  'dobs',
                                  'surface',
                                  comment_lines="SURFACE FORMAT")

        # Read DCIP2D files
        data_general = io_utils.read_dcip2d_ubc(
            self.dir_path + '/dc2d_general.txt', 'volt', 'general')
        data_surface = io_utils.read_dcip2d_ubc(
            self.dir_path + '/dc2d_surface.txt', 'volt', 'surface')

        # Compare
        passed = (np.all(
            np.isclose(data2D.dobs, data_general.dobs)
            & np.isclose(data2D.dobs, data_surface.dobs)))

        self.assertTrue(passed)
        print("READ/WRITE METHODS FOR DC2D DATA PASSED!")
Exemplo n.º 15
0
 def get_problem_survey(self, nx=20, ny=20, dx=10, dy=20):
     hx = np.ones(nx) * dx
     hy = np.ones(ny) * dy
     self._mesh_prop = TensorMesh([hx, hy])
     y = np.linspace(0, 400, 10)
     self._source_locations_prop = np.c_[y * 0 +
                                         self._mesh_prop.vectorCCx[0], y]
     self._receiver_locations_prop = np.c_[y * 0 +
                                           self._mesh_prop.vectorCCx[-1], y]
     rx = survey.BaseRx(self._receiver_locations_prop)
     srcList = [
         survey.BaseSrc(location=self._source_locations_prop[i, :],
                        receiver_list=[rx]) for i in range(y.size)
     ]
     self._survey_prop = seismic.survey.StraightRaySurvey(srcList)
     self._simulation_prop = seismic.simulation.Simulation2DIntegral(
         survey=self._survey_prop,
         mesh=self._mesh_prop,
         slownessMap=maps.IdentityMap(self._mesh_prop))
     self._data_prop = data.Data(self._survey_prop)
Exemplo n.º 16
0
    def set_geometric_factor(
        self,
        space_type="half-space",
        data_type=None,
        survey_type=None,
    ):
        if data_type is not None:
            raise TypeError(
                "The data_type kwarg has been removed, please set the data_type on the "
                "receiver object itself.")
        if survey_type is not None:
            raise TypeError("The survey_type parameter is no longer needed")

        geometric_factor = static_utils.geometric_factor(self,
                                                         space_type=space_type)

        geometric_factor = data.Data(self, geometric_factor)
        for source in self.source_list:
            for rx in source.receiver_list:
                if data_type is not None:
                    rx.data_type = data_type
                if rx.data_type == "apparent_resistivity":
                    rx._geometric_factor[source] = geometric_factor[source, rx]
        return geometric_factor
def resolve_1Dinversions(
    mesh,
    dobs,
    src_height,
    freqs,
    m0,
    mref,
    mapping,
    relative=0.08,
    floor=1e-14,
    rxOffset=7.86,
):
    """
    Perform a single 1D inversion for a RESOLVE sounding for Horizontal
    Coplanar Coil data (both real and imaginary).

    :param discretize.CylMesh mesh: mesh used for the forward simulation
    :param numpy.ndarray dobs: observed data
    :param float src_height: height of the source above the ground
    :param numpy.ndarray freqs: frequencies
    :param numpy.ndarray m0: starting model
    :param numpy.ndarray mref: reference model
    :param maps.IdentityMap mapping: mapping that maps the model to electrical conductivity
    :param float relative: percent error used to construct the data misfit term
    :param float floor: noise floor used to construct the data misfit term
    :param float rxOffset: offset between source and receiver.
    """

    # ------------------- Forward Simulation ------------------- #
    # set up the receivers
    bzr = FDEM.Rx.PointMagneticFluxDensitySecondary(np.array(
        [[rxOffset, 0.0, src_height]]),
                                                    orientation="z",
                                                    component="real")

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

    # source location
    srcLoc = np.array([0.0, 0.0, src_height])
    srcList = [
        FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation="Z")
        for freq in freqs
    ]

    # construct a forward simulation
    survey = FDEM.Survey(srcList)
    prb = FDEM.Simulation3DMagneticFluxDensity(mesh,
                                               sigmaMap=mapping,
                                               Solver=PardisoSolver)
    prb.survey = survey

    # ------------------- Inversion ------------------- #
    # data misfit term
    uncert = abs(dobs) * relative + floor
    dat = data.Data(dobs=dobs, standard_deviation=uncert)
    dmisfit = data_misfit.L2DataMisfit(simulation=prb, data=dat)

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

    # optimization
    opt = optimization.InexactGaussNewton(maxIter=10)

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

    # Inversion directives and parameters
    target = directives.TargetMisfit()
    inv = inversion.BaseInversion(invProb, directiveList=[target])

    invProb.beta = 2.0  # Fix beta in the nonlinear iterations
    reg.alpha_s = 1e-3
    reg.alpha_x = 1.0
    prb.counter = opt.counter = utils.Counter()
    opt.LSshorten = 0.5
    opt.remember("xc")

    # run the inversion
    mopt = inv.run(m0)
    return mopt, invProb.dpred, survey.dobs
Exemplo n.º 18
0
    if not os.path.exists(dir_path):
        os.mkdir(dir_path)

    # Add 10% Gaussian noise to each datum
    np.random.seed(225)
    std = 0.05 * np.abs(dpred)
    dc_noise = std * np.random.rand(len(dpred))
    dobs = dpred + dc_noise

    # Create a survey with the original electrode locations
    # and not the shifted ones
    # Generate source list for DC survey line
    source_list = generate_dcip_sources_line(
        survey_type,
        data_type,
        dimension_type,
        end_locations,
        topo_xyz,
        num_rx_per_src,
        station_separation,
    )
    survey_original = dc.survey.Survey(source_list)

    # Write out data at their original electrode locations (not shifted)
    data_obj = data.Data(survey_original, dobs=dobs, standard_deviation=std)
    fname = dir_path + "dc_data.obs"
    write_dcip2d_ubc(fname, data_obj, "volt", "dobs")

    fname = dir_path + "topo_xyz.txt"
    np.savetxt(fname, topo_xyz, fmt="%.4e")
Exemplo n.º 19
0
source_field = magnetics.sources.SourceField(receiver_list=receiver_list,
                                             parameters=inducing_field)

# Define the survey
survey = magnetics.survey.Survey(source_field)

#############################################
# Defining the Data
# -----------------
#
# Here is where we define the data that is inverted. The data is defined by
# the survey, the observation values and the standard deviations.
#

data_object = data.Data(survey, dobs=dobs, standard_deviation=std)

#############################################
# Defining a Tensor Mesh
# ----------------------
#
# Here, we create the tensor mesh that will be used to invert TMI data.
# If desired, we could define an OcTree mesh.
#

dh = 5.0
hx = [(dh, 5, -1.3), (dh, 40), (dh, 5, 1.3)]
hy = [(dh, 5, -1.3), (dh, 40), (dh, 5, 1.3)]
hz = [(dh, 5, -1.3), (dh, 15)]
mesh = TensorMesh([hx, hy, hz], "CCN")
Exemplo n.º 20
0
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)
Exemplo n.º 21
0
    M_locations = M_electrodes[k[ii]:k[ii + 1], :]
    N_locations = N_electrodes[k[ii]:k[ii + 1], :]
    receiver_list = [
        dc.receivers.Dipole(M_locations, N_locations, data_type="volt")
    ]

    # AB electrode locations for source. Each is a (1, 3) numpy array
    A_location = A_electrodes[k[ii], :]
    B_location = B_electrodes[k[ii], :]
    source_list.append(dc.sources.Dipole(receiver_list, A_location,
                                         B_location))

ip_survey = ip.survey.Survey(source_list)

# Define the a data object. Uncertainties are added later
dc_data = data.Data(dc_survey, dobs=dobs_dc)
ip_data = data.Data(ip_survey, dobs=dobs_ip)

# Plot apparent conductivity using pseudo-section
mpl.rcParams.update({"font.size": 12})
fig = plt.figure(figsize=(11, 9))

ax1 = fig.add_axes([0.05, 0.55, 0.8, 0.45])
plot_pseudosection(
    dc_data,
    ax=ax1,
    survey_type="dipole-dipole",
    data_type="appConductivity",
    space_type="half-space",
    scale="log",
    y_values="pseudo-depth",
Exemplo n.º 22
0
def read_gravity_gradiometry_3d_ubc(obs_file, file_type):
    """
    Read UBC gravity gradiometry file format

    INPUT:
    :param fileName, path to the UBC obs gravity gradiometry file
    :param file_type, 'dobs' 'dpred' 'survey'

    OUTPUT:
    :param survey

    """
    if file_type not in ["survey", "dpred", "dobs"]:
        raise ValueError("file_type must be one of: 'survey', 'dpred', 'dobs'")

    from SimPEG.potential_fields import gravity
    from SimPEG import data

    fid = open(obs_file, "r")

    # First line has components. Extract components
    line = fid.readline()
    line = line.split("=")[1].split("!")[0].split("\n")[0]
    line = line.replace(",", " ").split(" ")  # UBC uses ',' or ' ' as deliminator
    components = [s for s in line if len(s) > 0]  # Remove empty string
    factor = np.zeros(len(components))

    # Convert component types from UBC to SimPEG
    ubc_types = ["xx", "xy", "xz", "yy", "yz", "zz"]
    simpeg_types = ["gyy", "gxy", "gyz", "gxx", "gxz", "gzz"]
    factor_list = [1.0, 1.0, -1.0, 1.0, -1.0, 1.0]

    for ii in range(0, len(components)):
        k = ubc_types.index(components[ii])
        factor[ii] = factor_list[k]
        components[ii] = simpeg_types[k]

    # Second Line has number of locations
    line = fid.readline()
    ndat = int(line.split()[0])

    # Pre-allocate space for obsx, obsy, obsz, data, uncert
    line = fid.readline()

    locXYZ = np.zeros((ndat, 3), dtype=float)
    if file_type == "survey":
        d = None
        wd = None
    elif file_type == "dpred":
        d = np.zeros((ndat, len(components)), dtype=float)
        wd = None
    else:
        d = np.zeros((ndat, len(components)), dtype=float)
        wd = np.zeros((ndat, len(components)), dtype=float)

    ii = 0
    while ii < ndat:

        temp = np.array(line.split(), dtype=float)
        locXYZ[ii, :] = temp[:3]

        if file_type == "dpred":
            d[ii, :] = factor * temp[3:]

        elif file_type == "dobs":
            d[ii, :] = factor * temp[3::2]
            wd[ii, :] = temp[4::2]

        ii += 1
        line = fid.readline()
    fid.close()

    # Turn into vector. For multiple components, SimPEG orders by rows
    if d is not None:
        d = mkvc(d.T)
    if wd is not None:
        wd = mkvc(wd.T)

    rxLoc = gravity.receivers.Point(locXYZ, components=components)
    srcField = gravity.sources.SourceField([rxLoc])
    survey = gravity.survey.Survey(srcField)
    data_object = data.Data(survey, dobs=d, standard_deviation=wd)
    return data_object
Exemplo n.º 23
0
plt.show()

#######################################################
# Optional: Export Data
# ---------------------
#
# Write the data, topography and true model
#

if save_file:

    dir_path = os.path.dirname(magnetics.__file__).split(os.path.sep)[:-3]
    dir_path.extend(["tutorials", "assets", "magnetics"])
    dir_path = os.path.sep.join(dir_path) + os.path.sep

    fname = dir_path + "magnetics_topo.txt"
    np.savetxt(fname, np.c_[xyz_topo], fmt="%.4e")

    maximum_anomaly = np.max(np.abs(dpred))
    noise = 0.02 * maximum_anomaly * np.random.rand(len(dpred))
    fname = dir_path + "magnetics_data.obs"
    data_object = data.Data(survey,
                            dobs=dpred + noise,
                            standard_deviation=noise)
    utils.io_utils.writeUBCmagneticsObservations(fname, data_object)

    output_model = plotting_map * model
    output_model[np.isnan(output_model)] = 0.0
    fname = dir_path + "true_model.txt"
    mesh.writeModelUBC(fname, output_model)
Exemplo n.º 24
0
    # and not the shifted ones
    source_list = []
    for ii in range(0, len(end_locations_list)):
        source_list += generate_dcip_sources_line(
            survey_type,
            dc_data_type,
            dimension_type,
            end_locations_list[ii],
            topo_xyz,
            num_rx_per_src,
            station_separation,
        )
    dc_survey_original = dc.survey.Survey(source_list)
    
    # Write out data at their original electrode locations (not shifted)
    data_obj = data.Data(dc_survey_original, dobs=dobs, standard_deviation=std)
    
    fname = dir_path + "dc_data.xyz"
    write_dcip_xyz(
        fname,
        data_obj,
        data_header='V/A',
        uncertainties_header='UNCERT',
        out_dict=out_dict
    )


    # Add Gaussian noise with a standard deviation of 5e-3 V/V
    np.random.seed(444)
    std = 5e-3 * np.ones_like(dpred_ip)
    noise = std * np.random.rand(len(dpred_ip))
Exemplo n.º 25
0
def run(plotIt=True):

    # Define the inducing field parameter
    H0 = (50000, 90, 0)

    # Create a mesh
    dx = 5.0

    hxind = [(dx, 5, -1.3), (dx, 10), (dx, 5, 1.3)]
    hyind = [(dx, 5, -1.3), (dx, 10), (dx, 5, 1.3)]
    hzind = [(dx, 5, -1.3), (dx, 10)]

    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(-20.0, 20.0, 20)
    yr = np.linspace(-20.0, 20.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] + 5.0

    # Create a MAGsurvey
    rxLoc = np.c_[utils.mkvc(X.T), utils.mkvc(Y.T), utils.mkvc(Z.T)]
    rxLoc = magnetics.receivers.Point(rxLoc, components=["tmi"])
    srcField = magnetics.sources.SourceField(receiver_list=[rxLoc],
                                             parameters=H0)
    survey = magnetics.survey.Survey(srcField)

    # We can now create a susceptibility model and generate data
    # Here a simple block in half-space
    model = np.zeros((mesh.nCx, mesh.nCy, mesh.nCz))
    model[(midx - 2):(midx + 2), (midy - 2):(midy + 2), -6:-2] = 0.02
    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 model operator
    simulation = magnetics.simulation.Simulation3DIntegral(
        survey=survey,
        mesh=mesh,
        chiMap=idenMap,
        actInd=actv,
    )

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

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

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

    # Create a regularization
    reg = regularization.Sparse(mesh, indActive=actv, mapping=idenMap)
    reg.mref = np.zeros(nC)
    reg.norms = np.c_[0, 0, 0, 0]
    # reg.eps_p, reg.eps_q = 1e-0, 1e-0

    # Create sensitivity weights from our linear forward operator
    rxLoc = survey.source_field.receiver_list[0].locations
    m0 = np.ones(nC) * 1e-4  # Starting model

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

    # Add directives to the inversion
    opt = optimization.ProjectedGNCG(maxIter=20,
                                     lower=0.0,
                                     upper=1.0,
                                     maxIterLS=20,
                                     maxIterCG=20,
                                     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
    IRLS = directives.Update_IRLS(f_min_change=1e-3, max_irls_iterations=40)
    saveDict = directives.SaveOutputEveryIteration(save_txt=False)
    update_Jacobi = directives.UpdatePreconditioner()
    # Add sensitivity weights
    sensitivity_weights = directives.UpdateSensitivityWeights(everyIter=False)

    inv = inversion.BaseInversion(
        invProb,
        directiveList=[
            sensitivity_weights, IRLS, betaest, update_Jacobi, saveDict
        ],
    )

    # Run the inversion
    mrec = inv.run(m0)

    if plotIt:
        # Here is the recovered susceptibility model
        ypanel = midx
        zpanel = -5
        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

        # Plot the data
        utils.plot_utils.plot2Ddata(rxLoc, d)

        plt.figure()

        # Plot L2 model
        ax = plt.subplot(321)
        mesh.plotSlice(
            m_l2,
            ax=ax,
            normal="Z",
            ind=zpanel,
            grid=True,
            clim=(model.min(), model.max()),
        )
        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")

        # Vertica section
        ax = plt.subplot(322)
        mesh.plotSlice(
            m_l2,
            ax=ax,
            normal="Y",
            ind=midx,
            grid=True,
            clim=(model.min(), model.max()),
        )
        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=(model.min(), model.max()),
        )
        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=(model.min(), model.max()),
        )
        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=(model.min(), model.max()),
        )
        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=(model.min(), model.max()),
        )
        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_[IRLS.iterStart, IRLS.iterStart],
            np.r_[0, np.max(saveDict.phi_d)],
            "k:",
        )

        twin = axs.twinx()
        twin.plot(saveDict.phi_m, "k--", lw=2)
        axs.text(
            IRLS.iterStart,
            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)
Exemplo n.º 26
0
# Here we predict DC resistivity data. If the keyword argument *sigmaMap* is
# defined, the simulation will expect a conductivity model. If the keyword
# argument *rhoMap* is defined, the simulation will expect a resistivity model.
#

simulation = dc.simulation_2d.Simulation2DNodal(mesh,
                                                survey=survey,
                                                sigmaMap=conductivity_map,
                                                Solver=Solver)

# Predict the data by running the simulation. The data are the raw voltage in
# units of volts.
dpred = simulation.dpred(conductivity_model)

# Define a data object (required for pseudo-section plot)
data_obj = data.Data(survey, dobs=dpred)

# Plot apparent conductivity pseudo-section
fig = plt.figure(figsize=(12, 5))

ax1 = fig.add_axes([0.05, 0.05, 0.8, 0.9])
plot_pseudosection(
    data_obj,
    ax=ax1,
    survey_type="dipole-dipole",
    data_type="appConductivity",
    space_type="half-space",
    scale="log",
    y_values='pseudo-depth',
    pcolor_opts={"cmap": "viridis"},
)
# Create the simulation
simulation = magnetics.simulation.Simulation3DIntegral(survey=survey,
                                                       mesh=mesh,
                                                       chiMap=idenMap,
                                                       actInd=actv,
                                                       model_type="vector")

# Compute some data and add some random noise
d = simulation.dpred(mkvc(model))
std = 5  # nT
synthetic_data = d + np.random.randn(len(d)) * std
wd = np.ones(len(d)) * std

# Assign data and uncertainties to the survey
data_object = data.Data(survey, dobs=synthetic_data, standard_deviation=wd)

# Create an projection matrix for plotting later
actv_plot = maps.InjectActiveCells(mesh, actv, np.nan)

# Plot the model and data
plt.figure()
ax = plt.subplot(2, 1, 1)
im = utils.plot_utils.plot2Ddata(xyzLoc, synthetic_data, ax=ax)
plt.colorbar(im[0])
ax.set_title("Predicted data.")
plt.gca().set_aspect("equal", adjustable="box")

# Plot the vector model
ax = plt.subplot(2, 1, 2)
plotVectorSectionsOctree(
Exemplo n.º 28
0
    # MN electrode locations for receivers. Each is an (N, 3) numpy array
    M_locations = M_electrodes[k[ii] : k[ii + 1], :]
    N_locations = N_electrodes[k[ii] : k[ii + 1], :]
    receiver_list = [dc.receivers.Dipole(M_locations, N_locations, data_type="volt")]

    # AB electrode locations for source. Each is a (1, 3) numpy array
    A_location = A_electrodes[k[ii], :]
    B_location = B_electrodes[k[ii], :]
    source_list.append(dc.sources.Dipole(receiver_list, A_location, B_location))

# Define survey
survey = dc.survey.Survey_ky(source_list)

# Define the a data object. Uncertainties are added later
dc_data = data.Data(survey, dobs=dobs)

# Plot apparent conductivity using pseudo-section
mpl.rcParams.update({"font.size": 12})
fig = plt.figure(figsize=(12, 5))

ax1 = fig.add_axes([0.05, 0.05, 0.8, 0.9])
plot_pseudoSection(
    dc_data,
    ax=ax1,
    survey_type="dipole-dipole",
    data_type="appConductivity",
    space_type="half-space",
    scale="log",
    pcolorOpts={"cmap": "viridis"},
)
Exemplo n.º 29
0
# Define the source field
source_field = gravity.sources.SourceField(receiver_list=receiver_list)

# Define the survey
survey = gravity.survey.Survey(source_field)

#############################################
# Defining the Data
# -----------------
#
# Here is where we define the data that are inverted. The data are defined by
# the survey, the observation values and the standard deviation.
#

data_object = data.Data(survey, dobs=dobs, standard_deviation=uncertainties)

#############################################
# Defining a Tensor Mesh
# ----------------------
#
# Here, we create the tensor mesh that will be used to invert gravity anomaly
# data. If desired, we could define an OcTree mesh.
#

dh = 5.0
hx = [(dh, 5, -1.3), (dh, 40), (dh, 5, 1.3)]
hy = [(dh, 5, -1.3), (dh, 40), (dh, 5, 1.3)]
hz = [(dh, 5, -1.3), (dh, 15)]
mesh = TensorMesh([hx, hy, hz], "CCN")
Exemplo n.º 30
0
    tile_map = maps.TileMap(mesh, activeCells, local_meshes[ii])

    local_actives = tile_map.local_active

    # Create the forward simulation
    simulation = gravity.simulation.Simulation3DIntegral(
        survey=local_survey,
        mesh=local_meshes[ii],
        rhoMap=tile_map,
        actInd=local_actives,
        sensitivity_path=f"Inversion\Tile{ii}.zarr",
    )

    data_object = data.Data(
        local_survey,
        dobs=synthetic_data[local_indices[ii]],
        standard_deviation=wd[local_indices[ii]],
    )

    local_misfits.append(
        data_misfit.L2DataMisfit(data=data_object, simulation=simulation))

# Our global misfit
global_misfit = local_misfits[0] + local_misfits[1]

# Plot the model on different meshes
fig = plt.figure(figsize=(12, 6))
for ii, local_misfit in enumerate(local_misfits):

    local_mesh = local_misfit.simulation.mesh
    local_map = local_misfit.simulation.rhoMap