示例#1
0
distributed  data that are inside a given area. It doesn't matter whether or
not the points are on a regular grid.
"""
from fatiando import gridder
import matplotlib.pyplot as plt
import numpy as np

# Generate some synthetic data
area = (-100, 100, -60, 60)
x, y = gridder.scatter(area, 1000, seed=0)
data = np.sin(0.1*x)*np.cos(0.1*y)
# Select the data that fall inside "section"
section = [-40, 40, -25, 25]
# Tip: you pass more than one data array as input. Use this to cut multiple
# data sources (e.g., gravity + height + topography).
x_sub, y_sub, [data_sub] = gridder.cut(x, y, [data], section)

# Plot the original data besides the cut section
plt.figure(figsize=(8, 6))

plt.subplot(1, 2, 1)
plt.axis('scaled')
plt.title("Whole data")
plt.tricontourf(y, x, data, 30, cmap='RdBu_r')
plt.plot(y, x, 'xk')
x1, x2, y1, y2 = section
plt.plot([y1, y2, y2, y1, y1], [x1, x1, x2, x2, x1], '-k', linewidth=3)
plt.xlim(area[2:])
plt.ylim(area[:2])

plt.subplot(1, 2, 2)
"""
Gridding: Cut a section from a grid
"""
from fatiando import gridder, utils
from fatiando.vis import mpl

# Generate some synthetic data on a regular grid
x, y = gridder.regular((-10, 10, -10, 10), (100,100))
# Using a 2D Gaussian
z = utils.gaussian2d(x, y, 1, 1)
subarea = [-2, 2, -3, 3]
subx, suby, subscalar = gridder.cut(x, y, [z], subarea)

mpl.figure(figsize=(12, 5))
mpl.subplot(1, 2, 1)
mpl.title("Whole grid")
mpl.axis('scaled')
mpl.pcolor(x, y, z, (100,100))
mpl.square(subarea, 'k', linewidth=2, label='Cut this region')
mpl.legend(loc='lower left')
mpl.subplot(1, 2, 2)
mpl.title("Cut grid")
mpl.axis('scaled')
mpl.pcolor(subx, suby, subscalar[0], (40,60), interp=True)
mpl.show()
示例#3
0
def center_of_mass(x,
                   y,
                   z,
                   eigvec1,
                   windows=1,
                   wcenter=None,
                   wmin=None,
                   wmax=None):
    """
    Estimates the center of mass of a source using the method of Beiki and
    Pedersen (2010).

    Uses an expanding window to get the best estimate and deal with multiple
    sources.

    Parameters:

    * x, y, z : arrays
        The x, y, and z coordinates of the observation points
    * eigvec1 : array (shape = (N, 3) where N is the number of observations)
        The first eigenvector of the gravity gradient tensor at each observation
        point
    * windows : int
        The number of expanding windows to use
    * wcenter : list = [x, y]
        The [x, y] coordinates of the center of the expanding windows. Will
        default to the middle of the data area if None
    * wmin, wmax : float
        Minimum and maximum size of the expanding windows. Will default to
        10% data area and 100% data area, respectively, if None

    Returns:

    * [xo, yo, zo], sigma : float
        xo, yo, zo are the coordinates of the estimated center of mass. sigma is
        the estimated standard deviation of the distances between the estimated
        center of mass and the lines passing through the observation point in
        the direction of the eigenvector

    Example::

        >>> import fatiando as ft
        >>> # Generate synthetic data using a prism
        >>> prism = ft.mesher.Prism(-200,0,-100,100,0,200,{'density':1000})
        >>> x, y, z = ft.gridder.regular((-500,500,-500,500), (20,20), z=-100)
        >>> tensor = [ft.gravmag.prism.gxx(x, y, z, [prism]),
        ...           ft.gravmag.prism.gxy(x, y, z, [prism]),
        ...           ft.gravmag.prism.gxz(x, y, z, [prism]),
        ...           ft.gravmag.prism.gyy(x, y, z, [prism]),
        ...           ft.gravmag.prism.gyz(x, y, z, [prism]),
        ...           ft.gravmag.prism.gzz(x, y, z, [prism])]
        >>> # Get the eigenvector
        >>> eigenvals, eigenvecs = ft.gravmag.tensor.eigen(tensor)
        >>> # Now estimate the center of mass
        >>> cm, sigma = ft.gravmag.tensor.center_of_mass(x, y, z, eigenvecs[0])
        >>> xo, yo, zo = cm
        >>> print "%.2lf, %.2lf, %.2lf" % (xo, yo, zo)
        -100.05, 0.00, 99.86

    """
    if wmin is None:
        wmin = 0.1 * numpy.mean([x.max() - x.min(), y.max() - y.min()])
    if wmax is None:
        wmax = numpy.mean([x.max() - x.min(), y.max() - y.min()])
    # To ensure that if there is only one window, it will use the largest
    # possible
    if windows == 1:
        wmin = wmax
    if wcenter is None:
        wcenter = [0.5 * (x.min() + x.max()), 0.5 * (y.min() + y.max())]
    xc, yc = wcenter
    best = None
    for size in numpy.linspace(wmin, wmax, windows):
        area = [
            xc - 0.5 * size, xc + 0.5 * size, yc - 0.5 * size, yc + 0.5 * size
        ]
        wx, wy, scalars = gridder.cut(x, y, [z, eigvec1], area)
        wz, weigvec1 = scalars
        # Estimate the center of mass for the data in this window
        vx, vy, vz = numpy.transpose(weigvec1)
        m11 = numpy.sum(1 - vx**2)
        m12 = numpy.sum(-vx * vy)
        m13 = numpy.sum(-vx * vz)
        m22 = numpy.sum(1 - vy**2)
        m23 = numpy.sum(-vy * vz)
        m33 = numpy.sum(1 - vz**2)
        matrix = numpy.array([[m11, m12, m13], [m12, m22, m23],
                              [m13, m23, m33]])
        vector = numpy.array([
            numpy.sum((1 - vx**2) * wx - vx * vy * wy - vx * vz * wz),
            numpy.sum(-vx * vy * wx + (1 - vy**2) * wy - vy * vz * wz),
            numpy.sum(-vx * vz * wx - vy * vz * wy + (1 - vz**2) * wz)
        ])
        cm = numpy.linalg.solve(matrix, vector)
        xo, yo, zo = cm
        dists = ((xo - wx)**2 + (yo - wy)**2 + (zo - wz)**2 -
                 ((xo - wx) * vx + (yo - wy) * vy + (zo - wz) * vz)**2)
        sigma = numpy.sqrt(numpy.sum(dists) / len(wx))
        if best is None or sigma < best[1]:
            best = [cm, sigma]
    return best
示例#4
0
import numpy
from matplotlib import pyplot
from fatiando import vis, gridder, logger

log = logger.tofile(logger.get(), 'fetchdata.log')
log.info(logger.header())

data = numpy.loadtxt('/home/leo/dat/boa6/ftg/rawdata/BOA6_FTG.XYZ', unpack=True)
# Remove the coordinates from the raw data
data[0] -= data[0].min()
data[1] -= data[1].min()
area1 = [7970, 12877, 10650, 17270]
y, x, scalars = gridder.cut(data[0], data[1], data[2:], area1)
# The x and y components are switched because the coordinates are mixed up
# (my x is their y)
height, z, gyy, gxy, gyz, gxx, gxz, gzz = scalars
# Remove the coordinates from the cut data
x -= x.min()
y -= y.min()
# Convert altitude into z coordinates
z *= -1
# Save things to a file
fields =  ['x', 'y', 'height', 'alt', 'gxx', 'gxy', 'gxz', 'gyy', 'gyz', 'gzz']
data = [x, y, height, z, gxx, gxy, gxz, gyy, gyz, gzz]
with open('data.xyz', 'w') as f:
    f.write(logger.header(comment='#'))
    f.write("\n# Column structure\n# ")
    f.write('  '.join(fields))
    f.write('\n')
    numpy.savetxt(f, numpy.transpose(data), fmt="%.4f")
# Plot
示例#5
0
def center_of_mass(x, y, z, eigvec1, windows=1, wcenter=None, wmin=None,
    wmax=None):
    """
    Estimates the center of mass of a source using the method of Beiki and
    Pedersen (2010).

    Uses an expanding window to get the best estimate and deal with multiple
    sources.

    Parameters:

    * x, y, z : arrays
        The x, y, and z coordinates of the observation points
    * eigvec1 : array (shape = (N, 3) where N is the number of observations)
        The first eigenvector of the gravity gradient tensor at each observation
        point
    * windows : int
        The number of expanding windows to use
    * wcenter : list = [x, y]
        The [x, y] coordinates of the center of the expanding windows. Will
        default to the middle of the data area if None
    * wmin, wmax : float
        Minimum and maximum size of the expanding windows. Will default to
        10% data area and 100% data area, respectively, if None

    Returns:

    * [xo, yo, zo], sigma : float
        xo, yo, zo are the coordinates of the estimated center of mass. sigma is
        the estimated standard deviation of the distances between the estimated
        center of mass and the lines passing through the observation point in
        the direction of the eigenvector

    Example::

        >>> import fatiando as ft
        >>> # Generate synthetic data using a prism
        >>> prism = ft.mesher.Prism(-200,0,-100,100,0,200,{'density':1000})
        >>> x, y, z = ft.gridder.regular((-500,500,-500,500), (20,20), z=-100)
        >>> tensor = [ft.gravmag.prism.gxx(x, y, z, [prism]),
        ...           ft.gravmag.prism.gxy(x, y, z, [prism]),
        ...           ft.gravmag.prism.gxz(x, y, z, [prism]),
        ...           ft.gravmag.prism.gyy(x, y, z, [prism]),
        ...           ft.gravmag.prism.gyz(x, y, z, [prism]),
        ...           ft.gravmag.prism.gzz(x, y, z, [prism])]
        >>> # Get the eigenvector
        >>> eigenvals, eigenvecs = ft.gravmag.tensor.eigen(tensor)
        >>> # Now estimate the center of mass
        >>> cm, sigma = ft.gravmag.tensor.center_of_mass(x, y, z, eigenvecs[0])
        >>> xo, yo, zo = cm
        >>> print "%.2lf, %.2lf, %.2lf" % (xo, yo, zo)
        -100.05, 0.00, 99.86

    """
    if wmin is None:
        wmin = 0.1*numpy.mean([x.max() - x.min(), y.max() - y.min()])
    if wmax is None:
        wmax = numpy.mean([x.max() - x.min(), y.max() - y.min()])
    # To ensure that if there is only one window, it will use the largest
    # possible
    if windows == 1:
        wmin = wmax
    if wcenter is None:
        wcenter = [0.5*(x.min() + x.max()), 0.5*(y.min() + y.max())]
    xc, yc = wcenter
    best = None
    for size in numpy.linspace(wmin, wmax, windows):
        area = [xc - 0.5*size, xc + 0.5*size, yc - 0.5*size, yc + 0.5*size]
        wx, wy, scalars = gridder.cut(x, y, [z, eigvec1], area)
        wz, weigvec1 = scalars
        # Estimate the center of mass for the data in this window
        vx, vy, vz = numpy.transpose(weigvec1)
        m11 = numpy.sum(1 - vx**2)
        m12 = numpy.sum(-vx*vy)
        m13 = numpy.sum(-vx*vz)
        m22 = numpy.sum(1 - vy**2)
        m23 = numpy.sum(-vy*vz)
        m33 = numpy.sum(1 - vz**2)
        matrix = numpy.array(
            [[m11, m12, m13],
             [m12, m22, m23],
             [m13, m23, m33]])
        vector = numpy.array([
            numpy.sum((1 - vx**2)*wx - vx*vy*wy - vx*vz*wz),
            numpy.sum(-vx*vy*wx + (1 - vy**2)*wy - vy*vz*wz),
            numpy.sum(-vx*vz*wx - vy*vz*wy + (1 - vz**2)*wz)])
        cm = numpy.linalg.solve(matrix, vector)
        xo, yo, zo = cm
        dists = ((xo - wx)**2 + (yo - wy)**2 + (zo - wz)**2 -
                 ((xo - wx)*vx + (yo - wy)*vy + (zo - wz)*vz)**2)
        sigma = numpy.sqrt(numpy.sum(dists)/len(wx))
        if best is None or sigma < best[1]:
            best = [cm, sigma]
    return best
示例#6
0
"""
Gridding: Cut a section from a grid
"""
from fatiando import gridder, utils
from fatiando.vis import mpl

# Generate some synthetic data on a regular grid
x, y = gridder.regular((-10, 10, -10, 10), (100, 100))
# Using a 2D Gaussian
z = utils.gaussian2d(x, y, 1, 1)
subarea = [-2, 2, -3, 3]
subx, suby, subscalar = gridder.cut(x, y, [z], subarea)

mpl.figure(figsize=(12, 5))
mpl.subplot(1, 2, 1)
mpl.title("Whole grid")
mpl.axis('scaled')
mpl.pcolor(x, y, z, (100, 100))
mpl.square(subarea, 'k', linewidth=2, label='Cut this region')
mpl.legend(loc='lower left')
mpl.subplot(1, 2, 2)
mpl.title("Cut grid")
mpl.axis('scaled')
mpl.pcolor(subx, suby, subscalar[0], (40, 60), interp=True)
mpl.show()