Пример #1
0
    def test_box(self):
        dx = 0.25
        dl = 10

        # Create a box 2*dl in width
        X, Y, Z = np.meshgrid(np.c_[-dl, dl], np.c_[-dl, dl], np.c_[-dl, dl])
        xyz = np.c_[np.ravel(X), np.ravel(Y), np.ravel(Z)]
        mesh = meshutils.mesh_builder_xyz(
            np.c_[0.01, 0.01, 0.01], [dx, dx, dx],
            depth_core=0,
            padding_distance=[[0, 20], [0, 20], [0, 20]],
            mesh_type='TREE',
        )

        mesh = meshutils.refine_tree_xyz(
            mesh, xyz, octree_levels=[1], method='box', finalize=True
        )

        # Volume of box
        vol = (2*dl)**3

        residual = np.abs(
            vol -
            mesh.vol[
                mesh._cell_levels_by_indexes(range(mesh.nC)) == mesh.max_level
            ].sum()
        )/vol * 100

        self.assertTrue(residual < 0.5)
Пример #2
0
    def test_radial(self):
        dx = 0.25
        rad = 10
        mesh = meshutils.mesh_builder_xyz(
            np.c_[0.01, 0.01, 0.01], [dx, dx, dx],
            depth_core=0,
            padding_distance=[[0, 20], [0, 20], [0, 20]],
            mesh_type='TREE',
        )

        radCell = int(np.ceil(rad/dx))
        mesh = meshutils.refine_tree_xyz(
            mesh, np.c_[0, 0, 0],
            octree_levels=[radCell], method='radial',
            finalize=True
        )

        # Volume of sphere
        vol = 4.*np.pi/3.*rad**3.

        residual = np.abs(
            vol -
            mesh.vol[
                mesh._cell_levels_by_indexes(range(mesh.nC)) == mesh.max_level
            ].sum()
        )/vol * 100

        self.assertTrue(residual < 3)
Пример #3
0
    def test_surface(self):
        dx = 0.1
        dl = 20

        # Define triangle
        xyz = np.r_[
            np.c_[-dl/2, -dl/2, 0],
            np.c_[dl/2, -dl/2, 0],
            np.c_[dl/2, dl/2, 0]
        ]
        mesh = meshutils.mesh_builder_xyz(
            np.c_[0.01, 0.01, 0.01], [dx, dx, dx],
            depth_core=0,
            padding_distance=[[0, 20], [0, 20], [0, 20]],
            mesh_type='TREE',
        )

        mesh = meshutils.refine_tree_xyz(
            mesh, xyz, octree_levels=[1], method='surface', finalize=True
        )

        # Volume of triangle
        vol = dl*dl*dx/2

        residual = np.abs(
            vol -
            mesh.vol[
                mesh._cell_levels_by_indexes(range(mesh.nC)) == mesh.max_level
            ].sum()/2
        )/vol * 100

        self.assertTrue(residual < 5)
Пример #4
0
    def test_errors(self):
        dx = 0.25
        rad = 10
        self.assertRaises(ValueError, meshutils.mesh_builder_xyz,
            np.c_[0.01, 0.01, 0.01], [dx, dx, dx],
            depth_core=0,
            padding_distance=[[0, 20], [0, 20], [0, 20]],
            mesh_type='cyl',
        )

        mesh = meshutils.mesh_builder_xyz(
            np.c_[0.01, 0.01, 0.01], [dx, dx, dx],
            depth_core=0,
            padding_distance=[[0, 20], [0, 20], [0, 20]],
            mesh_type='tree',
        )

        radCell = int(np.ceil(rad/dx))
        self.assertRaises(NotImplementedError, meshutils.refine_tree_xyz,
            mesh, np.c_[0, 0, 0], octree_levels=[radCell], method='other',
            finalize=True
        )

        self.assertRaises(ValueError, meshutils.refine_tree_xyz,
            mesh, np.c_[0, 0, 0], octree_levels=[radCell],
            octree_levels_padding=[], method='surface',
            finalize=True
        )
Пример #5
0
def createLocalMesh(rxLoc, ind_t):
    """
    Function to generate a mesh based on receiver locations
    """

    # Create new survey
    if input_dict["inversion_type"] == 'grav':
        rxLoc_t = PF.BaseGrav.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseGrav.SrcField([rxLoc_t])
        local_survey = PF.BaseGrav.LinearSurvey(srcField)
        local_survey.dobs = survey.dobs[ind_t]
        local_survey.std = survey.std[ind_t]
        local_survey.ind = ind_t

    elif input_dict["inversion_type"] in ['mag', 'mvi', 'mvis']:
        rxLoc_t = PF.BaseMag.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseMag.SrcField([rxLoc_t], param=survey.srcField.param)
        local_survey = PF.BaseMag.LinearSurvey(
            srcField, components=survey.components
        )

        dataInd = np.kron(ind_t, np.ones(len(survey.components))).astype('bool')

        local_survey.dobs = survey.dobs[dataInd]
        local_survey.std = survey.std[dataInd]
        local_survey.ind = ind_t

    meshLocal = meshutils.mesh_builder_xyz(
        topo_elevations_at_data_locs,
        core_cell_size,
        padding_distance=padding_distance,
        mesh_type=inversion_mesh_type,
        base_mesh=input_mesh,
        depth_core=depth_core
    )

    if shift_mesh_z0 is not None:
        print("In mesh z0")
        meshLocal.x0 = np.r_[meshLocal.x0[0], meshLocal.x0[1], shift_mesh_z0]

    if inversion_mesh_type.upper() == 'TREE':
        if topo is not None:
            meshLocal = meshutils.refine_tree_xyz(
                meshLocal, topo, method='surface',
                octree_levels=octree_levels_topo, finalize=False
            )

        meshLocal = meshutils.refine_tree_xyz(
            meshLocal, topo_elevations_at_data_locs[ind_t, :],
            method='surface',
            max_distance=max_distance,
            octree_levels=octree_levels_obs,
            octree_levels_padding=octree_levels_padding,
            finalize=True,
        )

    # Create combo misfit function
    return meshLocal, local_survey
Пример #6
0
def createLocalMesh(rxLoc, ind_t):
    """
    Function to generate a mesh based on receiver locations
    """

    # Create new survey
    if input_dict["inversion_type"].lower() == 'grav':
        rxLoc_t = PF.BaseGrav.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseGrav.SrcField([rxLoc_t])
        local_survey = PF.BaseGrav.LinearSurvey(srcField)
        local_survey.dobs = survey.dobs[ind_t]
        local_survey.std = survey.std[ind_t]
        local_survey.ind = ind_t

        # Utils.io_utils.writeUBCgravityObservations(outDir + "Tile" + str(ind) + '.dat', local_survey, local_survey.dobs)

    elif input_dict["inversion_type"].lower() in ['mag', 'mvi', 'mvis']:
        rxLoc_t = PF.BaseMag.RxObs(rxLoc[ind_t, :])
        srcField = PF.BaseMag.SrcField([rxLoc_t], param=survey.srcField.param)
        local_survey = PF.BaseMag.LinearSurvey(srcField,
                                               components=survey.components)

        dataInd = np.kron(ind_t,
                          np.ones(len(survey.components))).astype('bool')

        local_survey.dobs = survey.dobs[dataInd]
        local_survey.std = survey.std[dataInd]
        local_survey.ind = ind_t

        # Utils.io_utils.writeUBCmagneticsObservations(outDir + "Tile" + str(ind) + '.dat', local_survey, local_survey.dobs)

    meshLocal = meshutils.mesh_builder_xyz(newTopo,
                                           core_cell_size,
                                           padding_distance=padding_distance,
                                           mesh_type='TREE',
                                           base_mesh=meshInput,
                                           depth_core=depth_core)

    if topo is not None:
        meshLocal = meshutils.refine_tree_xyz(meshLocal,
                                              topo,
                                              method='surface',
                                              octree_levels=octree_levels_topo,
                                              finalize=False)

    meshLocal = meshutils.refine_tree_xyz(
        meshLocal,
        rxLoc[ind_t, :],
        method='surface',
        max_distance=max_distance,
        octree_levels=octree_levels_obs,
        octree_levels_padding=octree_levels_padding,
        finalize=True,
    )

    # Create combo misfit function
    return meshLocal, local_survey
    def setUp(self):
        # We will assume a vertical inducing field
        H0 = (50000., 90., 0.)

        # The magnetization is set along a different direction (induced + remanence)
        M = np.array([90., 0.])

        # Block with an effective susceptibility
        chi_e = 0.05

        # Create grid of points for topography
        # Lets create a simple Gaussian topo and set the active cells
        [xx, yy] = np.meshgrid(np.linspace(-200, 200, 50),
                               np.linspace(-200, 200, 50))
        b = 100
        A = 50
        zz = A * np.exp(-0.5 * ((xx / b)**2. + (yy / b)**2.))
        topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)]

        # Create and array of observation points
        xr = np.linspace(-100., 100., 20)
        yr = np.linspace(-100., 100., 20)
        X, Y = np.meshgrid(xr, yr)
        Z = A * np.exp(-0.5 * ((X / b)**2. + (Y / b)**2.)) + 5

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

        # Create a mesh
        h = [5, 5, 5]
        padDist = np.ones((3, 2)) * 100
        nCpad = [4, 4, 2]

        self.mesh = meshutils.mesh_builder_xyz(
            xyzLoc,
            h,
            padding_distance=padDist,
            mesh_type='TREE',
        )

        self.mesh = meshutils.refine_tree_xyz(
            self.mesh,
            topo,
            method='surface',
            octree_levels=nCpad,
            octree_levels_padding=nCpad,
            finalize=True,
        )
        # Define an active cells from topo
        actv = Utils.surface2ind_topo(self.mesh, topo)
        nC = int(actv.sum())

        # Convert the inclination declination to vector in Cartesian
        M_xyz = Utils.matutils.dip_azimuth2cartesian(
            np.ones(nC) * M[0],
            np.ones(nC) * M[1])

        # Get the indicies of the magnetized block
        ind = Utils.ModelBuilder.getIndicesBlock(
            np.r_[-20, -20, -15],
            np.r_[20, 20, 20],
            self.mesh.gridCC,
        )[0]

        # Assign magnetization value, inducing field strength will
        # be applied in by the :class:`SimPEG.PF.Magnetics` problem
        model = np.zeros(self.mesh.nC)
        model[ind] = chi_e

        # Remove air cells
        self.model = model[actv]

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

        # Creat reduced identity map
        idenMap = Maps.IdentityMap(nP=nC)

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

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

        # Compute some data and add some random noise
        data = prob.fields(self.model)

        # Split the data in components
        nD = xyzLoc.shape[0]

        std = 5  # nT
        data += np.random.randn(nD) * std
        wd = np.ones(nD) * std

        # Assigne data and uncertainties to the survey
        survey.dobs = data
        survey.std = wd

        ######################################################################
        # Equivalent Source

        # Get the active cells for equivalent source is the top only
        surf = Utils.modelutils.surface_layer_index(self.mesh, topo)

        # Get the layer of cells directyl below topo
        nC = np.count_nonzero(surf)  # Number of active cells

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

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

        # Create static map
        prob = PF.Magnetics.MagneticIntegral(self.mesh,
                                             chiMap=idenMap,
                                             actInd=surf,
                                             parallelized=False,
                                             equiSourceLayer=True)

        prob.solverOpts['accuracyTol'] = 1e-4

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

        # Create a regularization function, in this case l2l2
        reg = Regularization.Sparse(self.mesh,
                                    indActive=surf,
                                    mapping=Maps.IdentityMap(nP=nC),
                                    scaledIRLS=False)
        reg.mref = np.zeros(nC)

        # Specify how the optimization will proceed,
        # set susceptibility bounds to inf
        opt = Optimization.ProjectedGNCG(maxIter=20,
                                         lower=-np.inf,
                                         upper=np.inf,
                                         maxIterLS=20,
                                         maxIterCG=20,
                                         tolCG=1e-3)

        # Define misfit function (obs-calc)
        dmis = DataMisfit.l2_DataMisfit(survey)
        dmis.W = 1. / survey.std

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

        # Specify how the initial beta is found
        betaest = Directives.BetaEstimate_ByEig()

        # Target misfit to stop the inversion,
        # try to fit as much as possible of the signal,
        # we don't want to lose anything
        IRLS = Directives.Update_IRLS(f_min_change=1e-3,
                                      minGNiter=1,
                                      beta_tol=1e-1)
        update_Jacobi = Directives.UpdatePreconditioner()
        # Put all the parts together
        inv = Inversion.BaseInversion(
            invProb, directiveList=[betaest, IRLS, update_Jacobi])

        # Run the equivalent source inversion
        mstart = np.ones(nC) * 1e-4
        mrec = inv.run(mstart)

        # Won't store the sensitivity and output 'xyz' data.
        prob.forwardOnly = True
        prob.rx_type = 'xyz'
        prob._G = None
        prob.modelType = 'amplitude'
        prob.model = mrec
        pred = prob.fields(mrec)

        bx = pred[:nD]
        by = pred[nD:2 * nD]
        bz = pred[2 * nD:]

        bAmp = (bx**2. + by**2. + bz**2.)**0.5

        # AMPLITUDE INVERSION
        # Create active map to go from reduce space to full
        actvMap = Maps.InjectActiveCells(self.mesh, actv, -100)
        nC = int(actv.sum())

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

        self.mstart = np.ones(nC) * 1e-4

        # Create the forward model operator
        prob = PF.Magnetics.MagneticIntegral(self.mesh,
                                             chiMap=idenMap,
                                             actInd=actv,
                                             modelType='amplitude',
                                             rx_type='xyz')
        prob.model = self.mstart
        # Change the survey to xyz components
        surveyAmp = PF.BaseMag.LinearSurvey(survey.srcField)

        # Pair the survey and problem
        surveyAmp.pair(prob)
        # Create a regularization function, in this case l2l2
        wr = np.sum(prob.G**2., axis=0)**0.5
        wr /= np.max(wr)
        # Re-set the observations to |B|
        surveyAmp.dobs = bAmp
        surveyAmp.std = wd

        # Create a sparse regularization
        reg = Regularization.Sparse(self.mesh, indActive=actv, mapping=idenMap)
        reg.norms = np.c_[0, 0, 0, 0]
        reg.mref = np.zeros(nC)
        reg.cell_weights = wr
        # Data misfit function
        dmis = DataMisfit.l2_DataMisfit(surveyAmp)
        dmis.W = 1. / surveyAmp.std

        # Add directives to the inversion
        opt = Optimization.ProjectedGNCG(maxIter=30,
                                         lower=0.,
                                         upper=1.,
                                         maxIterLS=20,
                                         maxIterCG=20,
                                         tolCG=1e-3)

        invProb = InvProblem.BaseInvProblem(dmis, reg, opt)

        # Here is the list of directives
        betaest = Directives.BetaEstimate_ByEig()

        # Specify the sparse norms
        IRLS = Directives.Update_IRLS(f_min_change=1e-3,
                                      minGNiter=1,
                                      coolingRate=1,
                                      betaSearch=False)

        # The sensitivity weights are update between each iteration.
        update_SensWeight = Directives.UpdateSensitivityWeights()
        update_Jacobi = Directives.UpdatePreconditioner()

        # Put all together
        self.inv = Inversion.BaseInversion(
            invProb,
            directiveList=[betaest, IRLS, update_SensWeight, update_Jacobi])
Пример #8
0
else:
    parallelized = True

if parallelized:
    dask.config.set({'array.chunk-size': str(max_chunk_size) + 'MiB'})
    dask.config.set(scheduler='threads')
    dask.config.set(num_workers=n_cpu)

if add_data_padding or decimate_to_mesh:
    # Scipy.interpolate flags divide-by-zero and invalid value errors when making
    # the mesh. They don't affect the result, so we suppress them temporarily.
    old_settings = np.seterr(divide='ignore', invalid='ignore')
    # Create a quadtree mesh using the same params as the full mesh
    decimate_mesh = meshutils.mesh_builder_xyz(
        survey.rxLoc[:, :2],
        core_cell_size[:2],
        padding_distance=padding_distance[:2],
        mesh_type='tree'
    )

    decimate_mesh = meshutils.refine_tree_xyz(
        decimate_mesh, survey.rxLoc[:, :2], method='surface',
        max_distance=max_distance,
        octree_levels=octree_levels_obs,
        octree_levels_padding=octree_levels_padding,
        finalize=True,
    )
    np.seterr(**old_settings)

    if decimate_to_mesh:
        print("Decimating the whole survey to the mesh")
        survey, data_trend = decimate_survey_to_mesh(decimate_mesh,
Пример #9
0
        tiles, binCount, tileIDs, tile_numbers = Utils.modelutils.tileSurveyPoints(
            rxLoc, count)

        # Grab the smallest bin and generate a temporary mesh
        indMax = np.argmax(binCount)

        X1, Y1 = tiles[0][:, 0], tiles[0][:, 1]
        X2, Y2 = tiles[1][:, 0], tiles[1][:, 1]

        ind_t = tileIDs == tile_numbers[indMax]

        # Create the mesh and refine the same as the global mesh
        meshLocal = meshutils.mesh_builder_xyz(
            newTopo,
            core_cell_size,
            padding_distance=padding_distance,
            mesh_type='TREE',
            base_mesh=meshInput,
            depth_core=depth_core)

        if topo is not None:
            meshLocal = meshutils.refine_tree_xyz(
                meshLocal,
                topo,
                method='surface',
                octree_levels=octree_levels_topo,
                finalize=False)

        meshLocal = meshutils.refine_tree_xyz(
            meshLocal,
            rxLoc[ind_t, :],
Пример #10
0
    # LOOP THROUGH TILES
    surveyMask = np.ones(survey.nD, dtype='bool')
    # Going through all problems:
    # 1- Pair the survey and problem
    # 2- Add up sensitivity weights
    # 3- Add to the ComboMisfit

    # Create first mesh outside the parallel process
    padDist = np.r_[np.c_[padLen, padLen], np.c_[padLen, padLen], np.c_[padLen,
                                                                        0]]

    if meshType != meshInput._meshType:
        print("Creating Global Octree")
        mesh = meshutils.mesh_builder_xyz(topo,
                                          h,
                                          padding_distance=padDist,
                                          mesh_type='TREE',
                                          base_mesh=meshInput,
                                          depth_core=depth_core)

        if topo is not None:
            mesh = meshutils.refine_tree_xyz(mesh,
                                             topo,
                                             method='surface',
                                             octree_levels=octreeTopo,
                                             finalize=False)

        mesh = meshutils.refine_tree_xyz(
            mesh,
            rxLoc,
            method='surface',
            max_distance=maxDist,
Пример #11
0
            tiles, binCount, tileIDs, tile_numbers = Utils.modelutils.tileSurveyPoints(
                rxLoc, count)

        # Grab the smallest bin and generate a temporary mesh
        indMax = np.argmax(binCount)

        X1, Y1 = tiles[0][:, 0], tiles[0][:, 1]
        X2, Y2 = tiles[1][:, 0], tiles[1][:, 1]

        ind_t = tileIDs == tile_numbers[indMax]

        # Create the mesh and refine the same as the global mesh
        meshLocal = meshutils.mesh_builder_xyz(
            topo_elevations_at_data_locs,
            core_cell_size,
            padding_distance=padding_distance,
            mesh_type='TREE',
            base_mesh=meshInput,
            depth_core=depth_core)

        if topo is not None:
            meshLocal = meshutils.refine_tree_xyz(
                meshLocal,
                topo,
                method='surface',
                octree_levels=octree_levels_topo,
                finalize=False)

        meshLocal = meshutils.refine_tree_xyz(
            meshLocal,
            topo_elevations_at_data_locs[ind_t, :],
Пример #12
0
    def setUp(self):

        np.random.seed(0)

        # First we need to define the direction of the inducing field
        # As a simple case, we pick a vertical inducing field of magnitude
        # 50,000nT.
        # From old convention, field orientation is given as an
        # azimuth from North (positive clockwise)
        # and dip from the horizontal (positive downward).
        H0 = (50000., 90., 0.)

        # Create a mesh
        h = [5, 5, 5]
        padDist = np.ones((3, 2)) * 100
        nCpad = [2, 4, 2]

        # Create grid of points for topography
        # Lets create a simple Gaussian topo and set the active cells
        [xx, yy] = np.meshgrid(np.linspace(-200., 200., 50),
                               np.linspace(-200., 200., 50))

        b = 100
        A = 50
        zz = A * np.exp(-0.5 * ((xx / b)**2. + (yy / b)**2.))

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

        # Create and array of observation points
        xr = np.linspace(-100., 100., 20)
        yr = np.linspace(-100., 100., 20)
        X, Y = np.meshgrid(xr, yr)
        Z = A * np.exp(-0.5 * ((X / b)**2. + (Y / b)**2.)) + 5

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

        # self.mesh.finalize()
        self.mesh = meshutils.mesh_builder_xyz(
            xyzLoc,
            h,
            padding_distance=padDist,
            mesh_type='TREE',
        )

        self.mesh = meshutils.refine_tree_xyz(
            self.mesh,
            topo,
            method='surface',
            octree_levels=nCpad,
            octree_levels_padding=nCpad,
            finalize=True,
        )

        # Define an active cells from topo
        actv = Utils.surface2ind_topo(self.mesh, topo)
        nC = int(actv.sum())

        # We can now create a susceptibility model and generate data
        # Lets start with a simple block in half-space
        self.model = Utils.ModelBuilder.addBlock(self.mesh.gridCC,
                                                 np.zeros(self.mesh.nC),
                                                 np.r_[-20, -20, -15],
                                                 np.r_[20, 20, 20], 0.05)[actv]

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

        # Creat reduced identity map
        idenMap = Maps.IdentityMap(nP=nC)

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

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

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

        # Add noise and uncertainties (1nT)
        noise = np.random.randn(len(data))
        data += noise
        wd = np.ones(len(data)) * 1.

        survey.dobs = data
        survey.std = wd

        # Create sensitivity weights from our linear forward operator
        rxLoc = survey.srcField.rxList[0].locs
        wr = prob.getJtJdiag(self.model)**0.5
        wr /= np.max(wr)

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

        reg.mref = np.zeros(nC)

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

        # Add directives to the inversion
        opt = Optimization.ProjectedGNCG(maxIter=20,
                                         lower=0.,
                                         upper=10.,
                                         maxIterLS=20,
                                         maxIterCG=20,
                                         tolCG=1e-4,
                                         stepOffBoundsFact=1e-4)

        invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e+6)

        # Here is where the norms are applied
        # Use pick a treshold parameter empirically based on the distribution of
        #  model parameters
        IRLS = Directives.Update_IRLS(f_min_change=1e-3,
                                      maxIRLSiter=20,
                                      beta_tol=1e-1,
                                      betaSearch=False)
        update_Jacobi = Directives.UpdatePreconditioner()

        # saveOuput = Directives.SaveOutputEveryIteration()
        # saveModel.fileName = work_dir + out_dir + 'ModelSus'
        self.inv = Inversion.BaseInversion(invProb,
                                           directiveList=[IRLS, update_Jacobi])
Пример #13
0
    def createLocalProb(rxLoc, wrGlobal, lims, ind):

        # 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

        meshLocal = meshutils.mesh_builder_xyz(topo,
                                               h,
                                               padding_distance=padDist,
                                               mesh_type='TREE',
                                               base_mesh=meshInput,
                                               depth_core=depth_core)

        if topo is not None:
            meshLocal = meshutils.refine_tree_xyz(meshLocal,
                                                  topo,
                                                  method='surface',
                                                  octree_levels=octreeTopo,
                                                  finalize=False)

        meshLocal = meshutils.refine_tree_xyz(
            meshLocal,
            rxLoc[ind_t, :],
            method='surface',
            max_distance=maxDist,
            octree_levels=octreeObs,
            octree_levels_padding=octreeObs_XY,
            finalize=True,
        )

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

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

        actv_t = tileMap.activeLocal

        print(actv_t.sum(), meshLocal.nC)
        # Create the forward model operator
        prob = PF.Magnetics.MagneticIntegral(meshLocal,
                                             chiMap=tileMap,
                                             actInd=actv_t,
                                             parallelized='dask',
                                             Jpath=work_dir + out_dir +
                                             "Tile" + str(ind) + ".zarr",
                                             store_zarr=True)

        survey_t.pair(prob)

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

        wr = prob.getJtJdiag(np.ones(tileMap.P.shape[1]), W=dmis.W)
        localMap = Maps.InjectActiveCells(meshLocal, actv_t, 1e-8)
        Mesh.TreeMesh.writeUBC(
            mesh,
            work_dir + out_dir + 'OctreeMesh' + str(tt) + '.msh',
            models={
                work_dir + out_dir + 'Wr_' + str(tt) + '.act': actvMap * wr
            })

        Mesh.TreeMesh.writeUBC(
            meshLocal,
            work_dir + out_dir + 'OctreeMesh' + str(tt) + '.msh',
            models={
                work_dir + out_dir + 'Wr_' + str(tt) + '.act':
                localMap * tileMap * wr
            })
        #    localMap = Maps.InjectActiveCells(meshLocal, actv_t, 1e-8)
        #    Mesh.TreeMesh.writeUBC(
        #                      meshLocal, work_dir + out_dir + 'OctreeMesh' + str(tt) + '.msh',
        #                      models={work_dir + out_dir + 'Wr_' + str(tt) + '.act': localMap*wr}
        #                    )
        #
        wrGlobal += wr

        del meshLocal

        # Create combo misfit function
        return dmis, wrGlobal
Пример #14
0
def createLocalProb(rxLoc, wrGlobal, ind_t, 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
    if input_dict["inversion_type"].lower() == 'grav':
        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

        Utils.io_utils.writeUBCgravityObservations(outDir + "Tile" + str(ind) + '.dat', survey_t, survey_t.dobs)

    elif input_dict["inversion_type"].lower() in ['mag', 'mvi']:
        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(outDir + "Tile" + str(ind) + '.dat', survey_t, survey_t.dobs)

    meshLocal = meshutils.mesh_builder_xyz(
        newTopo, core_cell_size, padding_distance=padding_distance, mesh_type='TREE', base_mesh=meshInput,
        depth_core=depth_core
    )

    if topo is not None:
        meshLocal = meshutils.refine_tree_xyz(
            meshLocal, topo, method='surface',
            octree_levels=octree_levels_topo, finalize=False
        )

    meshLocal = meshutils.refine_tree_xyz(
        meshLocal, rxLoc[ind_t, :], method='surface',
        max_distance=max_distance,
        octree_levels=octree_levels_obs,
        octree_levels_padding=octree_levels_padding,
        finalize=True,
    )

    # Need to find a way to compute sensitivities only for intersecting cells
    activeCells_t = np.ones(meshLocal.nC, dtype='bool')  # meshUtils.modelutils.activeTopoLayer(meshLocal, topo)

    # Create reduced identity map
    if input_dict["inversion_type"].lower() == 'mvi':
        nBlock = 3
    else:
        nBlock = 1

    tileMap = Maps.Tile((mesh, activeCells), (meshLocal, activeCells_t), nBlock=nBlock)

    activeCells_t = tileMap.activeLocal

    print(activeCells_t.sum(), meshLocal.nC)
    if input_dict["inversion_type"].lower() == 'grav':
        prob = PF.Gravity.GravityIntegral(
            meshLocal, rhoMap=tileMap, actInd=activeCells_t,
            parallelized=parallelized,
            Jpath=outDir + "Tile" + str(ind) + ".zarr",
            maxRAM=max_ram,
            n_cpu=n_cpu,
            )

    elif input_dict["inversion_type"].lower() == 'mag':
        prob = PF.Magnetics.MagneticIntegral(
            meshLocal, chiMap=tileMap, actInd=activeCells_t,
            parallelized=parallelized,
            Jpath=outDir + "Tile" + str(ind) + ".zarr",
            maxRAM=max_ram,
            n_cpu=n_cpu,
            )

    elif input_dict["inversion_type"].lower() == 'mvi':
        prob = PF.Magnetics.MagneticIntegral(
            meshLocal, chiMap=tileMap, actInd=activeCells_t,
            parallelized=parallelized,
            Jpath=outDir + "Tile" + str(ind) + ".zarr",
            maxRAM=max_ram,
            modelType='vector',
            n_cpu=n_cpu
        )

    survey_t.pair(prob)

    # Write out local active and obs for validation
    Mesh.TreeMesh.writeUBC(
      meshLocal, outDir + 'Octree_Tile' + str(ind) + '.msh',
      models={outDir + 'ActiveGlobal_Tile' + str(ind) + ' .act': activeCells_t}
    )

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

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

    wrGlobal += wr

    del meshLocal

    # Create combo misfit function
    return dmis
bounds = compute_bounds(surface.bounds, 0.1)
print(bounds)

###############################################################################

# Create a mesh based on data extent
h = [40, 40, 20]
pads = [[0, 0], [0, 0],[2000, 0]]
octreeTopo = [0,5,10,10]
octreeObs = [5, 5]
maxDist = 100
depth_core = 2500

mesh = meshutils.mesh_builder_xyz(
    topo, h,
    padding_distance=pads,
    mesh_type='TREE',
    depth_core=depth_core,
)

mesh = meshutils.refine_tree_xyz(mesh, topo,
                                 octree_levels=octreeTopo,
                                 method='surface', finalize=False)

mesh = meshutils.refine_tree_xyz(mesh, xyz,
                                 octree_levels=octreeObs,
                                 method='surface',
                                 max_distance=maxDist,
                                 finalize=True)

actv = modelutils.surface2ind_topo(mesh, topo, gridLoc='N')
Пример #16
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
        if driver["dataFile"][0] == 'GRAV':
            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

            Utils.io_utils.writeUBCgravityObservations(
                workDir + dsep + outDir + "Tile" + str(ind) + '.dat', survey_t,
                survey_t.dobs)

        elif driver["dataFile"][0] == 'MAG':
            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(
                workDir + dsep + outDir + "Tile" + str(ind) + '.dat', survey_t,
                survey_t.dobs)

        meshLocal = meshutils.mesh_builder_xyz(
            newTopo,
            h,
            padDist,
            mesh_type='TREE',
            depth_core=depth_core,
            base_mesh=meshInput,
        )

        if topo is not None:
            meshLocal = meshutils.refine_tree_xyz(meshLocal,
                                                  topo,
                                                  method='surface',
                                                  octree_levels=octreeTopo,
                                                  finalize=False)

        # Refine the mesh around loc
        meshLocal = meshutils.refine_tree_xyz(
            meshLocal,
            newTopo[ind_t, :],
            method='surface',
            octree_levels=octreeObs,
            octree_levels_padding=octree_levels_padding,
            finalize=True)

        # Need to find a way to compute sensitivities only for intersecting cells
        activeCells_t = np.ones(
            meshLocal.nC,
            dtype='bool')  # meshmeshutils.activeTopoLayer(meshLocal, topo)

        # Create reduced identity map
        tileMap = Maps.Tile((mesh, activeCells), (meshLocal, activeCells_t))

        activeCells_t = tileMap.activeLocal

        print(activeCells_t.sum(), meshLocal.nC)
        if driver["dataFile"][0] == 'GRAV':
            prob = PF.Gravity.GravityIntegral(meshLocal,
                                              rhoMap=tileMap,
                                              actInd=activeCells_t,
                                              parallelized=parallelized,
                                              Jpath=workDir + dsep + outDir +
                                              "Tile" + str(ind) + ".zarr",
                                              maxRAM=maxRAM / n_cpu,
                                              n_cpu=n_cpu,
                                              n_chunks=n_chunks)

        elif driver["dataFile"][0] == 'MAG':
            prob = PF.Magnetics.MagneticIntegral(
                meshLocal,
                chiMap=tileMap,
                actInd=activeCells_t,
                parallelized=parallelized,
                Jpath=workDir + dsep + outDir + "Tile" + str(ind) + ".zarr",
                maxRAM=maxRAM / n_cpu,
                n_cpu=n_cpu,
                n_chunks=n_chunks)

        survey_t.pair(prob)

        # Write out local active and obs for validation
        Mesh.TreeMesh.writeUBC(
            meshLocal,
            workDir + dsep + outDir + dsep + 'Octree_Tile' + str(ind) + '.msh',
            models={
                workDir + dsep + outDir + dsep + 'ActiveGlobal_Tile' + str(ind) + ' .act':
                activeCells_t
            })

        if driver["dataFile"][0] == 'GRAV':

            Utils.io_utils.writeUBCgravityObservations(
                workDir + dsep + outDir + dsep + 'Tile' + str(ind) + '.dat',
                survey_t, survey_t.dobs)

        elif driver["dataFile"][0] == 'MAG':

            Utils.io_utils.writeUBCmagneticsObservations(
                workDir + dsep + outDir + dsep + 'Tile' + str(ind) + '.dat',
                survey_t, survey_t.dobs)

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

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

        wrGlobal += wr

        del meshLocal

        # Create combo misfit function
        return dmis
Пример #17
0
# LOOP THROUGH TILES
surveyMask = np.ones(survey.nD, dtype='bool')
# Going through all problems:
# 1- Pair the survey and problem
# 2- Add up sensitivity weights
# 3- Add to the ComboMisfit

# Create first mesh outside the parallel process
padDist = np.r_[np.c_[padLen, padLen], np.c_[padLen, padLen], np.c_[padLen, 0]]

print("Creating Global Octree")
mesh = meshutils.mesh_builder_xyz(
    newTopo,
    h,
    padDist,
    mesh_type='TREE',
    depth_core=depth_core,
    base_mesh=meshInput,
)

if topo is not None:
    mesh = meshutils.refine_tree_xyz(mesh,
                                     topo,
                                     method='surface',
                                     octree_levels=octreeTopo,
                                     finalize=False)

mesh = meshutils.refine_tree_xyz(mesh,
                                 newTopo,
                                 method='surface',
                                 octree_levels=octreeObs,
Пример #18
0
    def setUp(self):

        np.random.seed(0)

        # First we need to define the direction of the inducing field
        # As a simple case, we pick a vertical inducing field of magnitude
        # 50,000nT.
        # From old convention, field orientation is given as an
        # azimuth from North (positive clockwise)
        # and dip from the horizontal (positive downward).
        H0 = (50000.0, 90.0, 0.0)

        # Create a mesh
        h = [5, 5, 5]
        padDist = np.ones((3, 2)) * 100
        nCpad = [2, 4, 2]

        # Create grid of points for topography
        # Lets create a simple Gaussian topo and set the active cells
        [xx, yy] = np.meshgrid(np.linspace(-200.0, 200.0, 50),
                               np.linspace(-200.0, 200.0, 50))

        b = 100
        A = 50
        zz = A * np.exp(-0.5 * ((xx / b)**2.0 + (yy / b)**2.0))

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

        # Create and array of observation points
        xr = np.linspace(-100.0, 100.0, 20)
        yr = np.linspace(-100.0, 100.0, 20)
        X, Y = np.meshgrid(xr, yr)
        Z = A * np.exp(-0.5 * ((X / b)**2.0 + (Y / b)**2.0)) + 5

        # Create a MAGsurvey
        xyzLoc = np.c_[utils.mkvc(X.T), utils.mkvc(Y.T), utils.mkvc(Z.T)]
        rxLoc = mag.Point(xyzLoc)
        srcField = mag.SourceField([rxLoc], parameters=H0)
        survey = mag.Survey(srcField)

        # self.mesh.finalize()
        self.mesh = meshutils.mesh_builder_xyz(
            xyzLoc,
            h,
            padding_distance=padDist,
            mesh_type="TREE",
        )

        self.mesh = meshutils.refine_tree_xyz(
            self.mesh,
            topo,
            method="surface",
            octree_levels=nCpad,
            octree_levels_padding=nCpad,
            finalize=True,
        )

        # Define an active cells from topo
        actv = utils.surface2ind_topo(self.mesh, topo)
        nC = int(actv.sum())

        # We can now create a susceptibility model and generate data
        # Lets start with a simple block in half-space
        self.model = utils.model_builder.addBlock(
            self.mesh.gridCC,
            np.zeros(self.mesh.nC),
            np.r_[-20, -20, -15],
            np.r_[20, 20, 20],
            0.05,
        )[actv]

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

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

        # Create the forward model operator
        sim = mag.Simulation3DIntegral(
            self.mesh,
            survey=survey,
            chiMap=idenMap,
            actInd=actv,
            store_sensitivities="ram",
        )
        self.sim = sim
        data = sim.make_synthetic_data(self.model,
                                       relative_error=0.0,
                                       noise_floor=1.0,
                                       add_noise=True)

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

        reg.mref = np.zeros(nC)

        # Data misfit function
        dmis = data_misfit.L2DataMisfit(simulation=sim, data=data)

        # Add directives to the inversion
        opt = optimization.ProjectedGNCG(
            maxIter=10,
            lower=0.0,
            upper=10.0,
            maxIterLS=5,
            maxIterCG=5,
            tolCG=1e-4,
            stepOffBoundsFact=1e-4,
        )

        invProb = inverse_problem.BaseInvProblem(dmis, reg, opt, beta=1e6)

        # Here is where the norms are applied
        # Use pick a treshold parameter empirically based on the distribution of
        #  model parameters
        IRLS = directives.Update_IRLS(f_min_change=1e-3,
                                      max_irls_iterations=20,
                                      beta_tol=1e-1,
                                      beta_search=False)
        update_Jacobi = directives.UpdatePreconditioner()
        sensitivity_weights = directives.UpdateSensitivityWeights()
        self.inv = inversion.BaseInversion(
            invProb, directiveList=[IRLS, sensitivity_weights, update_Jacobi])