Ejemplo n.º 1
0
    def test_sum(self):
        M2 = Mesh.TensorMesh([np.ones(10), np.ones(20)], "CC")
        block = (
            Maps.ParametricEllipsoid(M2) *
            Maps.Projection(7, np.r_[1, 2, 3, 4, 5, 6])
        )
        background = (
            Maps.ExpMap(M2) * Maps.SurjectFull(M2) *
            Maps.Projection(7, np.r_[0])
        )

        summap0 = Maps.SumMap([block, background])
        summap1 = block + background

        m0 = np.hstack([
            np.random.rand(3),
            np.r_[M2.x0[0], 2*M2.hx.min()],
            np.r_[M2.x0[1], 4*M2.hy.min()]
        ])

        self.assertTrue(
            np.all(summap0 * m0 == summap1 * m0)
        )

        self.assertTrue(summap0.test(m0))
        self.assertTrue(summap1.test(m0))
Ejemplo n.º 2
0
for unit in geoUnits:
#    if unit!=0:
    index += [mgeo==unit]
nC = len(index)

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

# Creat reduced identity map
homogMap = Maps.SurjectUnits(index)

# Create a wire map for a second model space
wires = Maps.Wires(('h**o', nC), ('hetero', len(actv)))

# Create Sum map
sumMap = Maps.SumMap([homogMap*wires.h**o, wires.hetero])


#%% Run inversion
prob = PF.Gravity.GravityIntegral(mesh, rhoMap=sumMap, actInd=actv)

survey.pair(prob)

#%%
# Load weighting  file

dmis = DataMisfit.l2_DataMisfit(survey)
dmis.W = 1./survey.std

wr = prob.getJtJdiag(np.ones(int(nC + len(actv))), W=dmis.W)
wr[wires.h**o.index] /= (np.max((wires.h**o*wr)))
Ejemplo n.º 3
0
    def createLocalProb(rxLoc, wrGlobal, lims, tileID):

        # Grab the data for current tile
        ind_t = np.all([rxLoc[:, 0] >= lims[0], rxLoc[:, 0] <= lims[1],
                        rxLoc[:, 1] >= lims[2], rxLoc[:, 1] <= lims[3],
                        surveyMask], axis=0)

        # Remember selected data in case of tile overlap
        surveyMask[ind_t] = False

        # Create new survey
        rxLoc_t = PF.BaseGrav.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseGrav.SrcField([rxLoc_t])
        survey_t = PF.BaseGrav.LinearSurvey(srcField)
        survey_t.dobs = survey.dobs[ind_t]
        survey_t.std = survey.std[ind_t]
        survey_t.ind = ind_t

        meshLocal = Utils.modelutils.meshBuilder(
            rxLoc, h, padDist, meshType='TREE', meshGlobal=meshInput,
            verticalAlignment='center'
        )

        if topo is not None:
            meshLocal = Utils.modelutils.refineTree(
                meshLocal, topo, dtype='surface',
                nCpad=octreeTopo, finalize=False
            )

        # Refine the mesh around loc
        meshLocal = Utils.modelutils.refineTree(
            meshLocal, rxLoc[ind_t, :], dtype='surface',
            nCpad=octreeObs, finalize=True
        )

        actv_t = np.ones(meshLocal.nC, dtype='bool')

        Mesh.TreeMesh.writeUBC(
              meshLocal,
              out_dir + 'OctreeMesh' + str(tt) + '.msh',
              models={
                out_dir + 'Active' + str(tileID) + '.act':
                actv_t
                }
            )

        # Create reduced identity map
        tileMap = Maps.Tile((mesh, actv), (meshLocal, actv_t))

        actv_t = tileMap.activeLocal

        # Interpolate the geo model
        _, ind = tree.query(meshLocal.gridCC)

        mgeo_t = ((fullMap * mgeo)[ind])[actv_t]

        # Build list of indecies for the geounits
        index = []
        for unit in geoUnits:
            index += [mgeo_t == unit]

        # Creat reduced identity map
        homogMap_t = Maps.SurjectUnits(index)

        # Create Sum map
        sumMap = Maps.SumMap([homogMap_t*wires.h**o, tileMap*wires.hetero])

        # Create the forward model operator
        prob = PF.Gravity.GravityIntegral(
            meshLocal, rhoMap=sumMap,
            actInd=actv_t,
            parallelized=parallization,
            Jpath=out_dir + "Tile" + str(tileID) + ".zarr",
            n_cpu=n_cpu
            )

        survey_t.pair(prob)

        # Data misfit function
        dmis = DataMisfit.l2_DataMisfit(survey_t)
        dmis.W = 1./survey_t.std

        wrGlobal += prob.getJtJdiag(np.ones(wires.h**o.shape[1]), W=dmis.W)

        del meshLocal

        # Create combo misfit function
        return dmis, wrGlobal
Ejemplo n.º 4
0
    def createLocalProb(rxLoc, wrGlobal, lims, ind):
        # createLocalProb(rxLoc, wrGlobal, lims, ind)
        # Generate a problem, calculate/store sensitivities for
        # given data points

        # Grab the data for current tile
        ind_t = np.all([
            rxLoc[:, 0] >= lims[0], rxLoc[:, 0] <= lims[1],
            rxLoc[:, 1] >= lims[2], rxLoc[:, 1] <= lims[3], surveyMask
        ],
                       axis=0)

        # Remember selected data in case of tile overlap
        surveyMask[ind_t] = False

        # Create new survey
        rxLoc_t = PF.BaseMag.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseMag.SrcField([rxLoc_t], param=survey.srcField.param)
        survey_t = PF.BaseMag.LinearSurvey(srcField)
        survey_t.dobs = survey.dobs[ind_t]
        survey_t.std = survey.std[ind_t]
        survey_t.ind = ind_t

        Utils.io_utils.writeUBCmagneticsObservations(
            out_dir + 'Tile' + str(tt) + 'dat', survey_t, survey_t.dobs)

        meshLocal = Utils.modelutils.meshBuilder(newTopo,
                                                 h,
                                                 padDist,
                                                 meshType='TREE',
                                                 meshGlobal=meshInput,
                                                 verticalAlignment='center')

        if topo is not None:
            meshLocal = Utils.modelutils.refineTree(meshLocal,
                                                    topo,
                                                    dtype='surface',
                                                    octreeLevels=octreeTopo,
                                                    finalize=False)

        # Refine the mesh around loc
        meshLocal = Utils.modelutils.refineTree(
            meshLocal,
            newTopo[ind_t, :],
            dtype='surface',
            octreeLevels=octreeObs,
            octreeLevels_XY=octreeObs_XY,
            finalize=True,
        )

        actv_t = np.ones(meshLocal.nC, dtype='bool')

        # Create reduced identity map
        tileMap = Maps.Tile((mesh, actv), (meshLocal, actv_t), nBlock=3)

        actv_t = tileMap.activeLocal

        if homogenizeMref:
            # Interpolate the geo model
            _, ind = tree.query(meshLocal.gridCC)

            mgeo_t = ((actvMap * mref)[ind])[actv_t]

            # Build list of indecies for the geounits
            index = []
            for unit in geoUnits:
                index += [mgeo_t == unit]

            # Creat reduced identity map
            homogMap_t = Maps.SurjectUnits(index)
            homogMap.nBlock = 3

            if modelDecomposition:
                # Create Sum map
                mapping = Maps.SumMap(
                    [homogMap_t * wires.h**o, tileMap * wires.hetero])

            else:
                mapping = homogMap_t * wires.h**o

        else:
            mapping = tileMap

        # Create the forward model operator
        prob = PF.Magnetics.MagneticIntegral(meshLocal,
                                             chiMap=mapping,
                                             actInd=actv_t,
                                             parallelized=parallelized,
                                             Jpath=out_dir + "Tile" +
                                             str(ind) + ".zarr",
                                             maxRAM=maxRAM,
                                             modelType='vector',
                                             n_cpu=np.ceil(n_cpu / nTiles))

        survey_t.pair(prob)

        # Data misfit function
        dmis = DataMisfit.l2_DataMisfit(survey_t)
        dmis.W = 1. / survey_t.std

        wr = prob.getJtJdiag(np.ones(int(mapping.shape[1])), W=dmis.W)

        actvMap_t = Maps.InjectActiveCells(meshLocal, actv_t, 1e-8)
        nC_t = int(actv_t.sum())
        Mesh.TreeMesh.writeUBC(
            meshLocal,
            out_dir + 'OctreeMesh' + str(tt) + '.msh',
            models={
                out_dir + 'Wr_' + str(tt) + '.act':
                actvMap_t * np.sum(
                    (tileMap * wr).reshape(nC_t, 3, order='F')**2., axis=1)**
                0.5
            })
        wrGlobal += wr

        del meshLocal
        # Create combo misfit function
        return dmis, wrGlobal
Ejemplo n.º 5
0
def run(plotIt=True):

    H0 = (50000., 90., 0.)

    # Create a mesh
    dx = 5.

    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 = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC')

    # 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]

    # Create and array of observation points
    xr = np.linspace(-20., 20., 20)
    yr = np.linspace(-20., 20., 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.

    # Create a MAGsurvey
    rxLoc = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)]
    rxLoc = PF.BaseMag.RxObs(rxLoc)
    srcField = PF.BaseMag.SrcField([rxLoc], param=H0)
    survey = PF.BaseMag.LinearSurvey(srcField)

    # We can now create a susceptibility model and generate data
    model = np.zeros(mesh.nC)

    # Change values in half the domain
    model[mesh.gridCC[:, 0] < 0] = 0.01

    # Add a block in half-space
    model = Utils.ModelBuilder.addBlock(mesh.gridCC, model,
                                        np.r_[-10, -10, 20], np.r_[10, 10,
                                                                   40], 0.05)

    model = Utils.mkvc(model)
    model = model[actv]

    # Create active map to go from reduce set to full
    actvMap = Maps.InjectActiveCells(mesh, actv, np.nan)

    # Create reduced identity map
    idenMap = Maps.IdentityMap(nP=len(actv))

    # Create the forward model operator
    prob = PF.Magnetics.MagneticIntegral(mesh, chiMap=idenMap, actInd=actv)

    # Pair the survey and problem
    survey.pair(prob)

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

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

    survey.dobs = data
    survey.std = wd
    survey.mtrue = model

    # Plot the data
    rxLoc = survey.srcField.rxList[0].locs

    # Create a homogenous maps for the two domains
    domains = [mesh.gridCC[actv, 0] < 0, mesh.gridCC[actv, 0] >= 0]
    homogMap = Maps.SurjectUnits(domains)

    # Create a wire map for a second model space, voxel based
    wires = Maps.Wires(('h**o', len(domains)), ('hetero', len(actv)))

    # Create Sum map
    sumMap = Maps.SumMap([homogMap * wires.h**o, wires.hetero])

    # Create the forward model operator
    prob = PF.Magnetics.MagneticIntegral(mesh, chiMap=sumMap, actInd=actv)

    # Pair the survey and problem
    survey.unpair()
    survey.pair(prob)

    # Make depth weighting
    wr = np.zeros(sumMap.shape[1])

    # Take the cell number out of the scaling.
    # Want to keep high sens for large volumes
    scale = Utils.sdiag(np.r_[Utils.mkvc(1. / homogMap.P.sum(axis=0)),
                              np.ones_like(actv)])

    for ii in range(survey.nD):
        wr += ((prob.G[ii, :] *
                prob.chiMap.deriv(np.ones(sumMap.shape[1]) * 1e-4) * scale) /
               survey.std[ii])**2.

    # Scale the model spaces independently
    wr[wires.h**o.index] /= (np.max((wires.h**o * wr)))
    wr[wires.hetero.index] /= (np.max(wires.hetero * wr))
    wr = wr**0.5

    ## Create a regularization
    # For the homogeneous model
    regMesh = Mesh.TensorMesh([len(domains)])

    reg_m1 = Regularization.Sparse(regMesh, mapping=wires.h**o)
    reg_m1.cell_weights = wires.h**o * wr
    reg_m1.norms = np.c_[0, 2, 2, 2]
    reg_m1.mref = np.zeros(sumMap.shape[1])

    # Regularization for the voxel model
    reg_m2 = Regularization.Sparse(mesh, indActive=actv, mapping=wires.hetero)
    reg_m2.cell_weights = wires.hetero * wr
    reg_m2.norms = np.c_[0, 1, 1, 1]
    reg_m2.mref = np.zeros(sumMap.shape[1])

    reg = reg_m1 + reg_m2

    # Data misfit function
    dmis = DataMisfit.l2_DataMisfit(survey)
    dmis.W = 1 / wd

    # Add directives to the inversion
    opt = Optimization.ProjectedGNCG(maxIter=100,
                                     lower=0.,
                                     upper=1.,
                                     maxIterLS=20,
                                     maxIterCG=10,
                                     tolCG=1e-3,
                                     tolG=1e-3,
                                     eps=1e-6)
    invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
    betaest = Directives.BetaEstimate_ByEig()

    # 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, minGNiter=1)
    update_Jacobi = Directives.UpdatePreconditioner()
    inv = Inversion.BaseInversion(invProb,
                                  directiveList=[IRLS, betaest, update_Jacobi])

    # Run the inversion
    m0 = np.ones(sumMap.shape[1]) * 1e-4  # Starting model
    prob.model = m0
    mrecSum = inv.run(m0)
    if plotIt:

        mesh.plot_3d_slicer(actvMap * model,
                            aspect="equal",
                            zslice=30,
                            pcolorOpts={"cmap": 'inferno_r'},
                            transparent='slider')

        mesh.plot_3d_slicer(actvMap * sumMap * mrecSum,
                            aspect="equal",
                            zslice=30,
                            pcolorOpts={"cmap": 'inferno_r'},
                            transparent='slider')