예제 #1
0
 def gen_kernel(self):
     self.kernel_matrices = []
     if self.cell_type == 'prism':
         for i in range(self.ns):
             xp = self.orig_data[self.orig_data['i_survey']==i]['x'].values
             yp = self.orig_data[self.orig_data['i_survey']==i]['y'].values
             zp = self.orig_data[self.orig_data['i_survey']==i]['z'].values
             kernel0 = np.zeros((len(xp),self.ny*self.nx))
             for j,cell in enumerate(self.mesh):
                 kernel0[:,j] = prism.gz(xp,yp,zp,[cell])
             self.kernel_matrices.append(np.array(kernel0))
     elif self.cell_type == 'tesseroid':
         for i in range(self.ns):
             xp = self.orig_data[self.orig_data['i_survey']==i]['lon'].values
             yp = self.orig_data[self.orig_data['i_survey']==i]['lat'].values
             zp = self.orig_data[self.orig_data['i_survey']==i]['z'].values
             kernel0 = np.zeros((len(xp),self.ny*self.nx))
             for j,cell in enumerate(self.mesh):
                 kernel0[:,j] = tesseroid.gz(xp,yp,zp,[cell])
             self.kernel_matrices.append(np.array(kernel0))
     else:
         raise ValueError('cell_type must be \'prism\' or \'tesseroid\'!!')
     self.kernel_op = AbicLSQOperatorMS(self.kernel_matrices,
                                        ns=self.ns,
                                        nzyx=(self.nz,self.ny,self.nx),
                                      smooth_components=self._smooth_components,
                                      weights=self._weights)
     self._gtg_exist = False
예제 #2
0
def migrate(x, y, z, gz, zmin, zmax, meshshape, power=0.5, scale=1):
    """
    3D potential field migration (Zhdanov et al., 2011).

    Actually uses the formula of Fedi and Pilkington (2012), which are
    comprehensible.

    .. note:: Only works on **gravity** data for now.

    .. note:: The data **do not** need to be leveled or on a regular grid.

    .. note:: The coordinate system adopted is x->North, y->East, and z->Down

    Parameters:

    * x, y : 1D-arrays
        The x and y coordinates of the grid points
    * z : float or 1D-array
        The z coordinate of the grid points
    * gz : 1D-array
        The gravity anomaly data at the grid points
    * zmin, zmax : float
        The top and bottom, respectively, of the region where the physical
        property distribution is calculated
    * meshshape : tuple = (nz, ny, nx)
        Number of prisms in the output mesh in the x, y, and z directions,
        respectively
    * power : float
        The power law used for the depth weighting. This controls what depth
        the bulk of the solution will be.
    * scale : float
        A scale factor for the depth weights. Simply changes the scale of the
        physical property values.

    Returns:

    * mesh : :class:`geoist.mesher.PrismMesh`
        The estimated physical property distribution set in a prism mesh (for
        easy 3D plotting)

    """
    nlayers, ny, nx = meshshape
    mesh = _makemesh(x, y, (ny, nx), zmin, zmax, nlayers)
    # This way, if z is not an array, it is now
    z = z * numpy.ones_like(x)
    dx, dy, dz = mesh.dims
    # Synthetic tests show that its not good to offset the weights with the
    # data z coordinate. No idea why
    depths = mesh.get_zs()[:-1] + 0.5 * dz
    weights = numpy.abs(depths)**power / (2 * G * numpy.sqrt(numpy.pi))
    density = []
    for l in range(nlayers):
        sensibility_T = numpy.array(
            [pot_prism.gz(x, y, z, [p], dens=1) for p in mesh.get_layer(l)])
        density.extend(scale * weights[l] * numpy.dot(sensibility_T, gz))
    mesh.addprop('density', numpy.array(density))
    return mesh
예제 #3
0
파일: freqinv1.py 프로젝트: mfkiwl/geoist
def gen_grav(shape = (100, 100)):

    dx = 6000/8.
    dy = 6000/8.
    dz = 1900/8.
    model = [geometry.Prism(-1000, 1000, -1000, 1000, 100, 2000, {'density': 1000}),
            geometry.Prism(-4000, -3000, -4000, -3000, 100, 2000, {'density': -900}),
            geometry.Prism(2000, 4000, 3000, 4000, 100, 2000, {'density': 1300})]
    prism1 = geometry.Prism(-3000+3*dx, -3000+4*dx, -3000+7*dy, -3000+8*dy, 100+4*dz, 100+5*dz, {'density': 2000})
    prism2 = geometry.Prism(-3000+2*dx, -3000+3*dx, -3000+2*dy, -3000+3*dy, 100+4*dz, 100+5*dz, {'density': 2000})
    model = [prism1,prism2]
    nzyx = [8,8,8]
    source_volume = [-3000, 3000, -3000, 3000, 100, 2000]
    xp, yp, zp = gridder.regular((-5000, 5000, -5000, 5000), shape, z=0)
    field0 = prism.gz(xp, yp, zp, model)
    fieldfreq = pftrans.gzfreq(xp, yp, zp, shape, model)
    #field1 = giutils.contaminate(field0, 0.05, percent = True)
    return field0, fieldfreq, xp, yp, zp
예제 #4
0
파일: inv3d.py 프로젝트: zhixin-xue/geoist
    def jacobian(self, p):
        """
        Build the Jacobian (sensitivity) matrix.

        The matrix will contain the length of the path takes by the ray inside
        each cell of the mesh.

        Parameters:

        * p : 1d-array
            An estimate of the parameter vector or ``None``.

        Returns:

        * jac : 2d-array (sparse CSR matrix from ``scipy.sparse``)
            The Jacobian

        """
        srcs = self.srcs
        xp, yp, zp = srcs
        kernel = []
        for i, layer in enumerate(self.mesh.layers()):
            for j, p in enumerate(layer):
                x1 = self.mesh.get_layer(i)[j].x1
                x2 = self.mesh.get_layer(i)[j].x2
                y1 = self.mesh.get_layer(i)[j].y1
                y2 = self.mesh.get_layer(i)[j].y2
                z1 = self.mesh.get_layer(i)[j].z1
                z2 = self.mesh.get_layer(i)[j].z2
                #den = self.mesh.get_layer(i)[j].props
                model = [
                    geometry.Prism(x1, x2, y1, y2, z1, z2, {'density': 1000})
                ]
                field = prism.gz(xp, yp, zp, model)
                kernel.append(field)
        #print(self.ndata, self.nparams)
        print(np.array(kernel).shape)
        return np.transpose(np.array(kernel))
예제 #5
0
파일: freqinv.py 프로젝트: mfkiwl/geoist
def gen_grav(shape=(100, 100)):

    model = [
        geometry.Prism(-1000, 1000, -1000, 1000, 100, 2000, {'density': 1000}),
        geometry.Prism(-4000, -3000, -4000, -3000, 100, 2000,
                       {'density': -900}),
        geometry.Prism(2000, 4000, 3000, 4000, 100, 2000, {'density': 1300})
    ]
    xp, yp, zp = gridder.regular((-5000, 5000, -5000, 5000), shape, z=0)
    field0 = prism.gz(xp, yp, zp, model)
    #prism.potential(xp, yp, zp, model)
    #field1 = giutils.contaminate(field0, 0.05, percent = True)
    fieldfreq = gzfreq(xp, yp, zp, shape, model)
    # fields = [prism.gx(xp, yp, zp, model),
    #           prism.gy(xp, yp, zp, model),
    #           prism.gz(xp, yp, zp, model),
    #           prism.gxx(xp, yp, zp, model),
    #           prism.gxy(xp, yp, zp, model),
    #           prism.gxz(xp, yp, zp, model),
    #           prism.gyy(xp, yp, zp, model),
    #           prism.gyz(xp, yp, zp, model),
    #           prism.gzz(xp, yp, zp, model)]

    return field0, fieldfreq, xp, yp, zp
예제 #6
0
from geoist.inversion import geometry
from geoist.pfm import prism
from geoist.vis import giplt

model = [
    geometry.Prism(-4000, -3000, -4000, -3000, 0, 2000, {'density': 1000}),
    geometry.Prism(-1000, 1000, -1000, 1000, 0, 2000, {'density': -900}),
    geometry.Prism(2000, 4000, 3000, 4000, 0, 2000, {'density': 1300})
]
shape = (100, 100)
xp, yp, zp = gridder.regular((-5000, 5000, -5000, 5000), shape, z=-150)
fields = [
    prism.potential(xp, yp, zp, model),
    prism.gx(xp, yp, zp, model),
    prism.gy(xp, yp, zp, model),
    prism.gz(xp, yp, zp, model),
    prism.gxx(xp, yp, zp, model),
    prism.gxy(xp, yp, zp, model),
    prism.gxz(xp, yp, zp, model),
    prism.gyy(xp, yp, zp, model),
    prism.gyz(xp, yp, zp, model),
    prism.gzz(xp, yp, zp, model)
]
titles = [
    'potential', 'gx', 'gy', 'gz', 'gxx', 'gxy', 'gxz', 'gyy', 'gyz', 'gzz'
]
plt.figure(figsize=(8, 9))
plt.subplots_adjust(left=0.03, right=0.95, bottom=0.05, top=0.92, hspace=0.3)
plt.suptitle("Potential fields produced by a 3 prism model")
for i, field in enumerate(fields):
    plt.subplot(4, 3, i + 3)
예제 #7
0
kernel=[] 
narea = (-28750, 28750,-48750, 48750) #NS, EW
nshape = (30, 40) #NS, EW
depthz = []
xp, yp, zp = gridder.regular(narea, nshape, z=-1)
for i, layer in enumerate(mesh.layers()):
    for j, p in enumerate(layer):
        x1 = mesh.get_layer(i)[j].x1
        x2 = mesh.get_layer(i)[j].x2
        y1 = mesh.get_layer(i)[j].y1
        y2 = mesh.get_layer(i)[j].y2
        z1 = mesh.get_layer(i)[j].z1
        z2 = mesh.get_layer(i)[j].z2
        den = mesh.get_layer(i)[j].props
        model=[geometry.Prism(x1, x2, y1, y2, z1, z2, {'density': 1000.})]
        field = prism.gz(xp, yp, zp, model)
        kernel.append(field)       
        depthz.append((z1+z2)/2.0)
kk=np.array(kernel)        
kk=np.transpose(kernel)  #kernel matrix for inversion, 500 cells * 400 points
field0=np.mat(kk)*np.transpose(np.mat(density.ravel()))

field = giutils.contaminate(np.array(field0).ravel(), 0.05, percent = True)

#零均值
print(field.mean())
#field = field + 300. # field.mean()
#画图

plt.figure(figsize=(16, 8))
plt.subplot(1, 2, 1)
예제 #8
0
"""
GravMag: Calculating the derivatives of the gravity anomaly using FFT
"""
import matplotlib.pyplot as plt
from geoist import gridder
from geoist.inversion import geometry
from geoist.pfm import prism, pftrans, giutils
from geoist.vis import giplt

model = [geometry.Prism(-1000, 1000, -1000, 1000, 0, 2000, {'density': 100})]
area = (-5000, 5000, -5000, 5000)
shape = (51, 51)
z0 = -500
xp, yp, zp = gridder.regular(area, shape, z=z0)
gz = giutils.contaminate(prism.gz(xp, yp, zp, model), 0.001)

# Need to convert gz to SI units so that the result can be converted to Eotvos
gxz = giutils.si2eotvos(pftrans.derivx(xp, yp, giutils.mgal2si(gz), shape))
gyz = giutils.si2eotvos(pftrans.derivy(xp, yp, giutils.mgal2si(gz), shape))
gzz = giutils.si2eotvos(pftrans.derivz(xp, yp, giutils.mgal2si(gz), shape))

gxz_true = prism.gxz(xp, yp, zp, model)
gyz_true = prism.gyz(xp, yp, zp, model)
gzz_true = prism.gzz(xp, yp, zp, model)

plt.figure()
plt.title("Original gravity anomaly")
plt.axis('scaled')
giplt.contourf(xp, yp, gz, shape, 15)
plt.colorbar(shrink=0.7)
giplt.m2km()
예제 #9
0
 def calc_kernel(i):
     return prism.gz(self.xp[0:1], self.yp[0:1], self.zp[0:1],
                     [self.mesh[i]])
예제 #10
0
    print('rhs recover misfit: ',
          np.linalg.norm(rhs - small_model.rhs) /
          np.linalg.norm(small_model.rhs))  # 方程右端项的检查。

    # save density model to vtk, comment out this section if gridToVTK not installed.

    #    nz,ny,nx = nzyx
    #    arr = small_model.solution.real.copy()
    #    xs = np.zeros((nz+1,ny+1,nx+1)) + np.array(small_model.mesh.get_xs()).reshape(1,1,-1)
    #    ys = np.zeros((nz+1,ny+1,nx+1)) + np.array(small_model.mesh.get_ys()).reshape(1,-1,1)
    #    zs = np.zeros((nz+1,ny+1,nx+1)) + np.array(small_model.mesh.get_zs()).reshape(-1,1,1)
    #    gridToVTK(str(work_dir/"results"),xs,ys,zs,cellData={"recover":arr.reshape(nz,ny,nx),
    #                                             "orig":model_density})
    #

    field0 = prism.gz(small_model.xp, small_model.yp, small_model.zp,
                      small_model.mesh)
    shape = (nobsyx[0], nobsyx[1])

    # plot field
    fig = plt.figure(figsize=(16, 8))
    # original field
    axes = fig.subplots(2, 2)
    #    plt.axis('scaled')
    ca = axes[0][0]
    plt.sca(ca)
    levels = giplt.contourf(small_model.yp * 0.001, small_model.xp * 0.001,
                            field0, shape, 15)
    cb = plt.colorbar()
    giplt.contour(small_model.yp * 0.001,
                  small_model.xp * 0.001,
                  field0,
예제 #11
0
# local imports
from geoist import gridder
from geoist.inversion import geometry
from geoist.pfm import prism, pftrans, giutils
from geoist.vis import giplt

model = [
    geometry.Prism(-3000, -2000, -3000, -2000, 500, 2000, {'density': 1000}),
    geometry.Prism(-1000, 1000, -1000, 1000, 0, 2000, {'density': -800}),
    geometry.Prism(1000, 3000, 2000, 3000, 0, 1000, {'density': 900})
]
area = (-5000, 5000, -5000, 5000)
shape = (50, 50)
z0 = -100
x, y, z = gridder.regular(area, shape, z=z0)
gz = giutils.contaminate(prism.gz(x, y, z, model), 0.5, seed=0)

height = 1000  # How much higher to go
gzcontf = pftrans.upcontinue(x, y, gz, shape, height)

# Compute the true value at the new height for comparison
gztrue = prism.gz(x, y, z - height, model)

args = dict(shape=shape, levels=20, cmap=plt.cm.RdBu_r)
fig, axes = plt.subplots(1, 3, figsize=(12, 3.5))
axes = axes.ravel()
plt.sca(axes[0])
plt.title("Original")
plt.axis('scaled')
giplt.contourf(x, y, gz, **args)
plt.colorbar(pad=0).set_label('mGal')