def test_plot(self): """ Should plot velocity grid with interfaces """ vm = VM('benchmark2d.vm') vm.plot()
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)
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)
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)
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)
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)
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)
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))
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))
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, "r") 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)
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)
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])
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)
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)
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)
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)))
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)
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)
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())
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):
""" 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)