示例#1
0
    def test_write_vm(self):
        """
        Should write in the native VM format
        """
        sl = np.random.rand(512, 1, 64)
        vm = VM(sl=sl)

        self.assertEqual(vm.grid.shape, sl.shape)
        self.assertAlmostEqual(vm.sl[0, 0, 0], sl[0, 0, 0], 7)

        fname = 'temp_out.vm'
        if os.path.isfile(fname):
            os.remove(fname)

        # should write to VM format
        vm.write(fname)
        self.assertTrue(os.path.isfile(fname))

        # should have the same data
        vm1 = VM(fname)
        self.assertEqual(vm1.sl.shape, vm.sl.shape)
        self.assertEqual(vm1.sl[0, 0, 0], vm.sl[0, 0, 0])
        self.assertEqual(vm1.sl[-1, -1, -1], vm.sl[-1, -1, -1])

        # clean up
        if os.path.isfile(fname):
            os.remove(fname)
示例#2
0
 def test_insert_interface(self):
     """
     Should insert a new interface
     """
     # Initialize a new model
     vm = VM(r1=(0, 0, 0), r2=(50, 0, 30), dx=0.5, dy=0.5, dz=0.5)
     # Should add a new, flat interface at 10 km
     z0 = 10.
     vm.insert_interface(z0 * np.ones((vm.nx, vm.ny)))
     self.assertEqual(vm.nr, 1)
     self.assertEqual(vm.rf[0].min(), z0)
     self.assertEqual(vm.rf[0].max(), z0)
     # New interfaces should have jp=0
     self.assertEqual(vm.jp[0].min(), 0)
     self.assertEqual(vm.jp[0].max(), 0)
     # New layers should have ir and ij = index of new interface
     self.assertEqual(vm.ir[0].min(), 0)
     self.assertEqual(vm.ir[0].max(), 0)
     self.assertEqual(vm.ij[0].min(), 0)
     self.assertEqual(vm.ij[0].max(), 0)
     # Adding a new interface should increase ir and ij of deeper layers
     for z0 in [5., 15., 1., 20.]:
         vm.insert_interface(z0 * np.ones((vm.nx, vm.ny)))
         for iref in range(0, vm.nr):
             self.assertEqual(vm.ir[iref].min(), iref)
             self.assertEqual(vm.ir[iref].max(), iref)
             self.assertEqual(vm.ij[iref].min(), iref)
             self.assertEqual(vm.ij[iref].max(), iref)
     # should take a scalar value for a constant depth interface
     vm = VM(r1=(0, 0, 0), r2=(50, 0, 30), dx=0.5, dy=0.5, dz=0.5)
     z0 = 10.
     vm.insert_interface(z0)
     self.assertEqual(vm.nr, 1)
     self.assertEqual(vm.rf[0].min(), z0)
     self.assertEqual(vm.rf[0].max(), z0)
示例#3
0
    def test_read_vm(self):
        """
        Should read the native VM format 
        """
        example_file = 'benchmark2d.vm'
        # make sure example can be found
        path = get_example_file(example_file)
        self.assertTrue(os.path.isfile(path))

        # should load the example file
        vm = VM(example_file, head_only=False)
        self.assertTrue(hasattr(vm, 'grid'))
        self.assertEqual(vm.grid.nx, 1041)
        self.assertEqual(vm.grid.ny, 1)
        self.assertEqual(vm.grid.nz, 506)
        self.assertEqual(vm.sl.shape[0], 1041)
        self.assertEqual(vm.sl.shape[1], 1)
        self.assertEqual(vm.sl.shape[2], 506)

        self.assertAlmostEqual(1. / vm.grid.values[0, 0, 0], 0.333, 3)

        self.assertEqual(vm.rf.shape, (5, vm.grid.nx, vm.grid.ny))
        self.assertEqual(vm.jp.shape, (5, vm.grid.nx, vm.grid.ny))
        self.assertEqual(vm.ir.shape, (5, vm.grid.nx, vm.grid.ny))
        self.assertEqual(vm.ij.shape, (5, vm.grid.nx, vm.grid.ny))
示例#4
0
    def test_plot(self):
        """
        Should plot velocity grid with interfaces
        """
        vm = VM('benchmark2d.vm')

        vm.plot()
示例#5
0
    def dev_raytrace(self):
        """
        Model should be compatible with the raytracer
        """
        #XXX testing with raytracer from Rockfish, for now
        #TODO update test with PyVM raytracer, when it exists

        from rockfish.tomography.forward import raytrace_from_ascii

        temp_path = 'temp_raytrace_input'
        if os.path.isdir(temp_path):
            shutil.rmtree(temp_path)

        os.makedirs(temp_path)

        # simple vm model
        shape = (128, 1, 64)
        vm = VM(shape=shape, dx=1, dy=1, dz=1)

        vm.insert_interface(5)

        vm.define_constant_layer_velocity(0, 1500)
        vm.define_constant_layer_gradient(1, 0.2)

        vmfile = os.path.join(temp_path, 'model.vm')
        vm.write(vmfile)

        self.assertTrue(os.path.isfile(vmfile))

        # simple geometry and picks
        instfile = os.path.join(temp_path, 'inst.dat')
        shotfile = os.path.join(temp_path, 'shot.dat')
        pickfile = os.path.join(temp_path, 'pick.dat')

        f = open(instfile, 'w')
        f.write('100 25. 0.0 3.0\n')
        f.write('101 30. 0.0 3.0\n')
        f.close()

        f = open(shotfile, 'w')
        f.write('9000 5. 0.0 0.006\n')
        f.write('9001 10. 0.0 0.006\n')
        f.close()

        f = open(pickfile, 'w')
        f.write('100 9000 1 0 9.999 9.999 0.000\n')
        f.write('101 9001 1 0 9.999 9.999 0.000\n')
        f.close()

        rayfile = os.path.join(temp_path, 'out.rays')
        raytrace_from_ascii(vmfile,
                            rayfile,
                            instfile=instfile,
                            shotfile=shotfile,
                            pickfile=pickfile,
                            verbose=1000)

        self.assertTrue(os.path.isfile(rayfile))
示例#6
0
    def test_init_model(self):
        """
        Should initialize a new model
        """
        shape = (128, 1, 64)
        vm = VM(shape=shape)

        # should have a created the 3D grid manager
        self.assertTrue(hasattr(vm, 'grid'))
        self.assertEqual(vm.grid.nx, shape[0])
        self.assertEqual(vm.grid.ny, shape[1])
        self.assertEqual(vm.grid.nz, shape[2])

        # should have default attributes needed by other routines
        for attr in [
                'sl', 'nr', 'nx', 'ny', 'nz', 'dx', 'dy', 'dz', 'rf', 'jp',
                'ij', 'ir', 'r1', 'r2', 'ilyr'
        ]:
            self.assertTrue(hasattr(vm, attr))

        # grid should be initialized to zeros
        self.assertEqual(vm.sl[0, 0, 0], 0)

        # setting certain aliases should set parent
        vm.sl[0, 0, 0] = 999
        self.assertEqual(vm.grid.values[0, 0, 0], 999)

        for attr in ['dx', 'dy', 'dz']:
            vm.__setattr__(attr, 999)
            self.assertEqual(vm.__getattribute__(attr), 999)
            self.assertEqual(vm.grid.__getattribute__(attr), 999)

        vm.r1 = (9.99, 8.88, 7.77)
        self.assertEqual(vm.r1, (9.99, 8.88, 7.77))
        self.assertEqual(vm.grid.origin, (9.99, 8.88, 7.77))

        # setting r2 should update grid spacing
        nx0, ny0, nz0 = vm.grid.shape[:]
        dx0, dy0, dz0 = vm.grid.spacing[:]

        vm.r2 = (400, 200, 300)
        self.assertEqual(vm.nx, nx0)
        self.assertEqual(vm.ny, ny0)
        self.assertEqual(vm.nz, nz0)
        self.assertNotEqual(vm.dx, dx0)
        self.assertNotEqual(vm.dy, dy0)
        self.assertNotEqual(vm.dz, dz0)

        # extents must be 3D
        for attr in ['r1', 'r2']:
            with self.assertRaises(ValueError) as context:
                vm.__setattr__(attr, (0, 0))

        # should not allow certain aliases to be set
        for attr in ['nx', 'ny', 'nz', 'nr']:
            with self.assertRaises(AttributeError) as context:
                vm.__setattr__(attr, 999)
示例#7
0
    def test_define_constant_layer_velocity(self):
        """
        Should flood a layer with one velocity
        """
        vm = VM()

        vm.insert_interface(5)

        vm.define_constant_layer_velocity(0, vel=8.5)
        self.assertAlmostEqual(vm.sl[0, 0, 0], 1. / 8.5, 6)

        vm.define_constant_layer_velocity(1, vel=9.5)
        self.assertAlmostEqual(1. / np.min(vm.sl), 9.5, 6)
示例#8
0
    def test_define_stretched_layer_velocities(self):
        """
        Should stretch a velocity function to fit within a layer
        """
        vm = VM()

        vm.insert_interface(5)

        vm.define_stretched_layer_velocities(0, vel=[1.500, 1.500])
        self.assertAlmostEqual(vm.sl[0, 0, 0], 1. / 1.5, 7)

        vm.define_stretched_layer_velocities(1, vel=[None, 8.1])

        self.assertAlmostEqual(1. / np.min(vm.sl), 8.1, 6)
示例#9
0
    def test_ilyr(self):
        """
        Should assign grid nodes to layers
        """
        shape = (128, 1, 64)
        vm = VM(shape=shape)

        # top layer should be 0
        for i in vm.ilyr.flatten():
            self.assertEqual(i, 0)

        # last layer should be equal to the number of interfaces
        for nr in [1, 2, 10]:
            vm.rf = 5 * np.ones((nr, vm.nx, vm.ny))
            self.assertEqual(np.max(vm.ilyr), nr)
示例#10
0
    def test_define_constant_layer_gradient(self):
        """
        Should define a constant layer gradient in a layer
        """
        vm = VM()

        vm.insert_interface(5)

        vm.define_constant_layer_gradient(0, 0, v0=1.500)

        self.assertAlmostEqual(vm.sl[0, 0, 0], 1. / 1.5, 7)

        vm.define_constant_layer_gradient(1, 0.1, v0=3.0)

        self.assertAlmostEqual(1. / np.min(vm.sl), 15.19999945, 7)
示例#11
0
    def dev_readwrite_interface_flags(self):
        """
        Should handle Fortran vs. Python indexing for interface flags
        """
        sl = np.random.rand(8, 1, 12)
        vm = VM(sl=sl)

        vm.insert_interface(1)

        vm.ir = np.zeros((1, vm.nx, vm.ny))
        vm.ij = np.zeros((1, vm.nx, vm.ny))

        fname = 'temp_out.vm'
        if os.path.isfile(fname):
            os.remove(fname)

        vm.write(fname)

        # writing should not change flags
        for ilyr in range(vm.nr):
            for ix in range(vm.nx):
                for iy in range(vm.ny):
                    self.assertEqual(vm.ir[ilyr, ix, iy], 0)
                    self.assertEqual(vm.ij[ilyr, ix, iy], 0)

        # read should handle -1 for indexing
        vm1 = VM(fname)
        for ilyr in range(vm1.nr):
            for ix in range(vm1.nx):
                for iy in range(vm1.ny):
                    self.assertEqual(vm1.ir[ilyr, ix, iy], 0)
                    self.assertEqual(vm1.ij[ilyr, ix, iy], 0)

        # clean up
        if os.path.isfile(fname):
            os.remove(fname)
示例#12
0
    def __init__(self, pickdb=None, model=None, rays=None):

        if pickdb:
            self.pickdb = pickdb
        else:
            self.pickdb = PickDatabase()

        if isinstance(model, VM):
            # connect to existing model instance
            self.model = model
        else:
            # create a new default model or read existing file
            self.model = VM(filename=model)

        if rays:
            self.rays = rays
示例#13
0
    def test_fix_pinchouts(self):
        """
        Should fix layer pinchouts so that boundaries do not cross 
        """
        vm = VM()

        z = np.reshape(2 + 0.05 * (vm.grid.x), (vm.nx, 1))
        vm.insert_interface(z)

        vm.insert_interface(6)

        nerror0 = len(np.nonzero((vm.rf[1] - vm.rf[0]) < 0)[0])
        assert nerror0 > 0

        # should fix crossings and pinchouts
        vm.fix_pinchouts()
        nerror = len(np.nonzero((vm.rf[1] - vm.rf[0]) < 0)[0])
        self.assertEqual(nerror, 0)
示例#14
0
    def test_r1_r2(self):
        """
        Should force reflectors to be the same shape as the grid
        """
        shape = (128, 1, 64)
        vm = VM(shape=shape)

        for attr in ['rf', 'jp', 'ir', 'ij']:
            # should allow (nr, nx, ny)-sized arrays
            vm.__setattr__(attr, np.ones((1, vm.nx, vm.ny)))
            self.assertEqual(vm.nr, 1)

            # should not allow other sizes
            with self.assertRaises(ValueError) as context:
                vm.__setattr__(attr, np.ones((1, 999, vm.ny)))

            with self.assertRaises(ValueError) as context:
                vm.__setattr__(attr, np.ones((1, vm.nx, 999)))
示例#15
0
    def test_verify(self):
        """
        Should inherit verify functions 
        """

        shape = (128, 1, 64)
        vm = VM(shape=shape)
        vm.sl = np.ones(vm.sl.shape)

        self.assertTrue(hasattr(vm, 'verify'))
        self.assertTrue(vm.verify())

        # should return false if NaNs are on the grid
        vm.sl[0, 0, 0] = np.nan
        self.assertFalse(vm.verify())

        # should return false if zeros are on the grid
        vm.sl = np.ones(vm.sl.shape)
        self.assertTrue(vm.verify())
        vm.sl[0, 0, 0] = 0.0
        self.assertFalse(vm.verify())
示例#16
0
    def test_write_bin(self):
        """
        Should write grid to headerless binary format
        """
        sl = np.random.rand(512, 1, 64)
        vm = VM(sl=sl)

        fname = 'temp_out.bin'
        if os.path.isfile(fname):
            os.remove(fname)

        vm.write(fname)

        f = open(fname, 'rb')
        dat = np.fromstring(f.read(), dtype='float32').reshape(sl.shape)

        for v1, v2 in zip(dat.flatten(), vm.sl.flatten()):
            self.assertEqual(v1, v2)

        if os.path.isfile(fname):
            os.remove(fname)
示例#17
0
    def test_get_layer_bounds(self):
        """
        Should get surfaces bounding a layer.
        """
        shape = (128, 1, 64)
        vm = VM(shape=shape)

        # top and bottom should be model boundary if no layers
        self.assertEqual(vm.nr, 0)

        z0, z1 = vm.get_layer_bounds(0)

        for _z in z0:
            self.assertEqual(_z, vm.r1[2])

        for _z in z1:
            self.assertEqual(_z, vm.r2[2])

        # bottom of first layer should be first interface
        vm.rf = 5 * np.ones((1, vm.nx, vm.ny))
        z0, z1 = vm.get_layer_bounds(0)

        for _z in z0:
            self.assertEqual(_z, vm.r1[2])

        for _z in z1:
            self.assertEqual(_z, 5)

        # top of second layer should be first interface
        z0, z1 = vm.get_layer_bounds(1)

        for _z in z0:
            self.assertEqual(_z, 5)

        for _z in z1:
            self.assertEqual(_z, vm.r2[2])
示例#18
0
import numpy as np
from pyvm.models.vm import VM

# define the model domain in terms of grid dimensions, spacing, and origin
ny = 460
vm = VM(shape=(500, ny, 100), spacing=(1, 1, 1), origin=(0, 0, -5))

##

# sloping boundary - SEA FLOOR & BATHYMETRY
specs = [  #xstart, xend, slope
    [0., 230., 0], [230., 275., -0.05], [275., 330., 0], [330., 350., 0.07],
    [350., 400., 0], [400., 450., -0.04], [450., 500., 0]
]
z0 = 0  # intial depth at left-hand side of model

# build full boundary
z = np.ones(vm.nx)
for x0, x1, m in specs:
    ix = vm.xrange2i(x0, x1)
    x = vm.grid.x[ix]
    z[ix] = z0 + m * (x - x[0])
    z0 = z[ix[-1]]

# expand into 3D
n = np.ones((vm.nx, 1))
for i in range(0, ny):
    n[i] = z[i]

s = np.ones((vm.nx, vm.ny))
for i in range(0, ny):
示例#19
0
def raytrace_from_ascii(vmfile,
                        rayfile,
                        instfile='inst.dat',
                        shotfile='shot.dat',
                        pickfile='pick.dat',
                        grid_size=None,
                        forward_star_size=[12, 12, 24],
                        min_angle=0.5,
                        min_velocity=1.4,
                        max_node_size=620,
                        top_layer=0,
                        bottom_layer=None,
                        stdout=None,
                        stderr=None,
                        verbose=True):
    """
    Wrapper for running the VM Tomography raytracer using a ASCII input files.

    Parameters
    ----------
    vmfile : str
        Filename of the VM Tomography slowness model to raytrace.
    rayfile : str
        Filename of the output VM Tomography rayfan file.
    instfile : str
        Filename of the ASCII-formatted instrument location file with 
        the four columns: ``inst_id, x, y, z``.
    shotfile : str
        Filename of the ASCII-formatted shot location file with 
        the four columns: ``shot_id, x, y, z``.
    pickfile : str
        Filename of the ASCII-formatted pick time file with 
        the seven columns: ``inst_id, shot_id, branch, subbranch_id, range,
        pick_time, pick_error``.
    grid_size : (int, int, int), optional
        Tuple of ``(nx, ny, nz)`` dimensions for the graphing grid. Default is        to match the graphing grid to the slowness model dimensions.
    min_angle : float, optional
        Minimum angle between search directions in forward star in degrees.
    min_velocity : float, optional
        Minimum velocity to trace rays through.
    max_node_size : int, optional
        Average number of nodes to allocate for each raypath. The raytracing
        program will adjust this size if needed.
    top_layer : int, optional
        The index of the top-most layer to trace rays through.
    bottom_layer : int, optional
        The index of the bottom-most layer to trace rays through. Default is
        the index of the bottom-most layer in the model.
    stdout, stderr : {'PIPE', int, file, None}, optional
        stdout and stderr specify the raytracing program's standard
        output and standard error file handles, respectively. Valid values
        are ``'PIPE'``, an existing file descriptor (a positive
        integer), an existing file object, and ``None``. See :mod:`subprocess`        for more information.
    verbose : {bool, int}, optional
        Determines whether or not to print information from the
        raytracing program.  Valid values are ``True``, ``False``, or numeric
        level.
    """
    # set numeric verbosity level
    if verbose and (type(verbose) == bool):
        verbose = 4
    #XXX # ensure full path for vm programs
    #vmfile = os.path.abspath(vmfile)
    #rayfile = os.path.abspath(rayfile)
    # set grid size for shortest path algortithm
    vm = VM(vmfile)
    if grid_size is None:
        grid_size = (vm.nx, vm.ny, vm.nz)
    # set forward star size for 2D cases
    if vm.nx == 1:
        forward_star_size[0] = 0
    elif vm.ny == 1:
        forward_star_size[1] = 0
    # Set bottom-most layer
    if bottom_layer is None:
        bottom_layer = vm.nr
    # Get instrument locations
    finst = open(instfile, 'rb')
    inst = {}
    for row in finst:
        dat = row.split()
        inst[int(dat[0])] = [float(d) for d in dat[1:4]]
    finst.close()
    # Raytrace each instrument
    ninst = len(inst)
    if verbose >= 2:
        print('Raytracing paths to {:} receiver(s)...'.format(ninst))
    if os.path.isfile(rayfile):
        os.remove(rayfile)
    start_all = time.clock()
    for i, _inst in enumerate(inst):
        # Set flag to leave rayfan file open for additional instruments
        if i == 0:
            irayfile_exists = 0
        else:
            irayfile_exists = 1
        recx, recy, recz = inst[_inst]
        # Build input
        if verbose >= 3:
            print(' Tracing rays for receiver #{:} ({:} of {:})'\
                    .format(_inst, i + 1, ninst))
        sh = '#!/bin/bash\n'
        sh += '#\n'
        sh += '{:} << eof\n'.format(RAYTR_PROGRAM)
        sh += '{:}\n'.format(vmfile)
        sh += '{:}\n'.format(_inst)
        sh += '{:},{:},{:}\n'.format(grid_size[0], grid_size[1], grid_size[2])
        sh += '{:}\n'.format(1. / min_velocity)
        sh += '{:}\n'.format(max_node_size)
        sh += '{:<10.5f} {:<10.5f} {:<10.5f}\n'.format(recx, recy, recz)
        sh += '{:},{:}\n'.format(top_layer, bottom_layer)
        sh += '{:},{:},{:}\n'.format(forward_star_size[0],
                                     forward_star_size[1],
                                     forward_star_size[2])
        sh += '{:}\n'.format(min_angle)
        sh += '{:}\n'.format(shotfile)
        sh += '{:}\n'.format(pickfile)
        sh += '{:}\n'.format(rayfile)
        sh += '{:}\n'.format(irayfile_exists)
        sh += '0.0\n'  # XXX seting instrument static to 0. here!
        # TODO take as input
        sh += 'eof\n'

        start = time.clock()
        if os.path.isfile(rayfile):
            raysize0 = os.path.getsize(rayfile)
        else:
            raysize0 = 0

        if (verbose >= 4):
            print(sh)

        if (verbose >= 4) or (stdout is not None):
            subprocess.call(sh, shell=True, stdout=stdout, stderr=stderr)
        else:
            with open(os.devnull, "w") as fnull:
                subprocess.call(sh, shell=True, stdout=fnull, stderr=stderr)
        elapsed = (time.clock() - start)
        if os.path.isfile(rayfile):
            raysize1 = os.path.getsize(rayfile)
        else:
            raysize1 = 0
        if (raysize1 == raysize0) and verbose >= 1:
            msg = 'Did not appear to trace rays for receiver #{:}'\
                    .format(_inst)
            warnings.warn(msg)
        if verbose >= 3:
            print('Completed raytracing for receiver #{:} in {:} seconds.'\
                .format(_inst, elapsed))
    if verbose >= 2:
        print('Completed raytracing for all recievers in {:} seconds.'\
                .format(time.clock() - start_all))
    if os.path.isfile(rayfile) and verbose > 1:
        print('Output rayfile is: {:}'.format(rayfile))
    elif not os.path.isfile(rayfile) and (verbose >= 1):
        msg = 'Did not create a rayfile.'
        warnings.warn(msg)
示例#20
0
import numpy as np
import copy
import matplotlib.pyplot as plt

from pyvm.models.vm import VM

vm = VM('Myers_3D.vm')

rf0 = copy.copy(vm.rf[0][:, :])

fig = plt.figure(figsize=(20, 10))

ax = fig.add_subplot(131)
ax.imshow(np.flipud(rf0.T))

plt.title('Before smoothing')

vm.smooth_interface(0, nwin=25)

ax = fig.add_subplot(132)
ax.imshow(np.flipud(vm.rf[0].T))
plt.title('After smoothing')

ax = fig.add_subplot(133)
ax.imshow(np.flipud((vm.rf[0] - rf0).T), cmap='seismic')
plt.title('Difference')

plt.show()
示例#21
0
"""
Build a simple VM model from scratch
"""
import numpy as np
from pyvm.models.vm import VM

# create a 2D model
vm = VM(shape=(512, 1, 256), spacing=(0.5, 1, 0.1), origin=(412, 412, -2))

# add interfaces
vm.insert_interface(0)
vm.insert_interface(3)
vm.insert_interface(5)
vm.insert_interface(12)

# add velocities
vm.define_constant_layer_velocity(0, 0.333)
vm.define_stretched_layer_velocities(1, vel=[1.49, 1.51])
vm.define_stretched_layer_velocities(2, vel=[None, 2.3])
vm.define_stretched_layer_velocities(3, vel=[4.4, 6.8, 6.9, 7.2])
vm.define_constant_layer_gradient(4, 0.1)

# plot
vm.plot(aspect=10)