def dev_grids(self): """ Should use a separate class to manage grids """ vm = readVM(get_example_file('1d.vm')) # should have the grid class self.assertTrue(hasattr(vm, 'grids')) self.assertTrue(isinstance(vm.grids, VMGrids)) # should still have the 'sl' alias for the slowness grid self.assertTrue(hasattr(vm, 'sl')) sl0 = copy.copy(vm.sl) # save original slowness grid # modifying vm.sl should update vm.grids.slowness self.assertTrue(vm.sl is vm.grids.slowness) vm.sl = 999.99 self.assertTrue(vm.grids.slowness == 999.99) # and visa versa vm.grids.slowness = 888.88 self.assertTrue(vm.sl == 888.88) # grids should also have velocity and twt self.assertTrue(hasattr(vm.grids, 'velocity')) self.assertTrue(hasattr(vm.grids, 'twt')) # these grids should be the same shape as sl for n0, n1 in zip(vm.sl.shape, vm.grids.velocity.shape): self.assertEqual(n0, n1) for n0, n1 in zip(vm.sl.shape, vm.grids.twt.shape): self.assertEqual(n0, n1)
def test_read_write_vm(self): """ Reading and writing in the VM format should not change data. """ # read data from the disk file vmfile = get_example_file(BENCHMARK_2D) vm = readVM(vmfile) # check values self.compare_to_benchmark(vm) # write it to another file tmp = 'temp.vm' vm.write(tmp) # read these data back in vm = readVM(tmp) # check values self.compare_to_benchmark(vm) # clean up os.remove(tmp)
def test_boundary_flags(self): """ Should convert boundary flags from fortran to python index conventions """ for model in TEST_MODELS: # read anymodel with interfaces vm = readVM(get_example_file(model)) # set all ir and ij flags to -1 (off) vm.ir = -1 * np.ones(vm.ir.shape) vm.ij = -1 * np.ones(vm.ij.shape) # reading and writing should not change flag values tempvm = 'temp123.vm' vm.write(tempvm) vm = readVM(tempvm) self.assertEqual(vm.ir.min(), -1) self.assertEqual(vm.ir.max(), -1) self.assertEqual(vm.ij.min(), -1) self.assertEqual(vm.ij.max(), -1) # cleanup os.remove(tempvm)
def test__get_layers(self): """ Should return the layer index of each node on the grid. """ for model in TEST_MODELS: vm = readVM(get_example_file(model)) layers = vm._get_layers() # should have an entry for each node self.assertEqual(layers.shape, (vm.nx, vm.ny, vm.nz)) # should have nodes in each layer # assuming no complete pinchouts self.assertEqual(len(np.unique(layers)), vm.nr + 1)
def test_define_stretched_layer_velocities(self): """ Should fit a 1D velocity function to a layer. """ for model in TEST_MODELS: vm = readVM(get_example_file(model)) # should define constant velocities within layer for ilyr in range(vm.nr + 1): vm.sl = np.nan * np.ones((vm.nx, vm.ny, vm.nz)) vm.define_stretched_layer_velocities(ilyr, [10]) self.assertEqual(np.nanmax(vm.sl), 1. / 10) self.assertEqual(np.nanmin(vm.sl), 1. / 10)
def test_insert_layer_velocities(self): """ Should insert velocities into a layer. """ for model in TEST_MODELS: vm = readVM(get_example_file(model)) # should define constant velocities within layer for ilyr in range(vm.nr + 1): vm.sl = np.nan * np.ones((vm.nx, vm.ny, vm.nz)) sl = 10 * np.ones((vm.nx, vm.ny, vm.nz)) vm.insert_layer_velocities(ilyr, sl, is_slowness=True) self.assertEqual(np.nanmax(vm.sl), 10) self.assertEqual(np.nanmin(vm.sl), 10)
def test_project_model_points(self): """ Should map 2d model points to points in the 3d model. """ phi = 30. vm3d = VM(r1=(100, 200, 0), r2=(500, 300, 30), dx=5, dy=5, dz=1) for model in TEST_MODELS: vm2d = readVM(get_example_file(model)) # default should return valid coordinates x = project_model_points(vm2d, vm3d, phi) self.assertTrue(np.min(x) >= vm2d.r1[0]) self.assertTrue(np.max(x) <= vm2d.r2[0]) # indices = True should return valid indices ix = project_model_points(vm2d, vm3d, phi) self.assertTrue(np.min(ix) >= 0) self.assertTrue(np.max(ix) <= vm2d.nx)
def test_raytrace_branch_id(self): """ Raytracing should honor branch ids """ #vmfile = get_example_file('jump1d.vm') vmfile = get_example_file('inactive_layers.vm') # Create pick database pickdbfile = 'temp.sqlite' if os.path.isfile(pickdbfile): os.remove(pickdbfile) pickdb = PickDatabaseConnection(pickdbfile) pickdb.update_pick(event='P1', ensemble=100, trace=1, branch=1, subbranch=0, time=5.0, source_x=10, source_y=0.0, source_z=0.006, receiver_x=40, receiver_y=0.0, receiver_z=4.9) pickdb.update_pick(event='P2', ensemble=100, trace=1, branch=2, subbranch=0, time=5.0) pickdb.update_pick(event='P3', ensemble=100, trace=1, branch=3, subbranch=0, time=5.0) pickdb.commit() # Raytrace vm = readVM(vmfile) rayfile = 'temp.ray' for branch in range(1, 4): if os.path.isfile(rayfile): os.remove(rayfile) pick_keys = {'branch' : branch} raytrace(vmfile, pickdb, rayfile, **pick_keys) # Should have created a rayfile self.assertTrue(os.path.isfile(rayfile)) # Load rayfans rays = readRayfanGroup(rayfile) # Should have traced just one ray self.assertEqual(len(rays.rayfans), 1) rfn = rays.rayfans[0] self.assertEqual(len(rfn.paths), 1) # Rays should turn in specified layer zmax = max([p[2] for p in rfn.paths[0]]) self.assertGreaterEqual(zmax, vm.rf[branch - 1][0][0]) # cleanup for filename in [rayfile, pickdbfile]: if os.path.isfile(filename): os.remove(filename)
def test_two2three(self, sol=(0, 0), theta=39): """ Should create a 3D model from a 2D model. """ for test_model in TEST_MODELS: vm2d = readVM(get_example_file(test_model)) # calculate example endpoints line_len = np.sqrt((vm2d.r2[0] - vm2d.r1[0]) ** 2 +\ (vm2d.r2[1] - vm2d.r1[1]) ** 2) eol = (sol[0] + line_len * np.cos(np.deg2rad(theta)), sol[1] + line_len * np.sin(np.deg2rad(theta))) # should create 3d model vm3d = two2three(vm2d, sol, eol, dx=1, dy=1) # check bounds self.assertAlmostEqual(vm3d.r1[0], sol[0], 0) self.assertAlmostEqual(vm3d.r1[1], sol[1], 0) self.assertAlmostEqual(vm3d.r2[0], eol[0], 0) self.assertAlmostEqual(vm3d.r2[1], eol[1], 0) # spot check some values for iref in range(0, vm3d.nr): self.assertAlmostEqual(vm3d.rf[iref].min(), vm2d.rf[iref].min(), 1) self.assertAlmostEqual(vm3d.rf[iref].max(), vm2d.rf[iref].max(), 1)
def test_locate_on_surface(self): """ Should locate a receiver on a surface. """ inst_id = 100 dx = 1 iref = 0 for _vmfile in TEST_MODELS: vmfile = get_example_file(_vmfile) vm = readVM(vmfile) # calculate synthetic times pickdb = PickDatabaseConnection(':memory:') x0 = np.mean(vm.x) y0 = np.mean(vm.y) picks = [] xsearch = vm.xrange2i(max(vm.r1[0], x0 - dx), min(vm.r2[0], x0 + dx)) for i, ix in enumerate(xsearch): x = vm.x[ix] iy = vm.x2i([y0])[0] z0 = vm.rf[iref][ix][iy] pickdb.add_pick(event='Pw', ensemble=inst_id, trace=i, time=1e30, source_x=x, source_y=y0, source_z=0.006, receiver_x=x0, receiver_y=y0, receiver_z=z0, vm_branch=1, vm_subid=0) rayfile = 'temp.ray' raytrace(vmfile, pickdb, rayfile) raydb = rayfan2db(rayfile, 'temp.syn.sqlite', synthetic=True) os.remove(rayfile) # run locate x, y, z, rms = locate_on_surface(vmfile, raydb, 0, x0=x0, y0=y0, dx=dx, dy=dx) # compare result self.assertAlmostEqual(x, x0, 0) self.assertAlmostEqual(y, y0, 0)
def locate_on_surface(vmfile, pickdb, iref, pick_keys={}, x0=None, y0=None, dx=None, dy=None, plot=False): """ Locate a receiver on a surface. :param vmfile: Filename of the VM Tomography slowness model to raytrace. :param pickdb: :class:`rockfish.picking.database.PickDatabaseConnection` to get picks from for raytracing. :param iref: index of the surface to move the receiver on :param pick_keys: Optional. ``dict`` of keys and values to use for selecting picks from ``pickdb``. Default is to use all picks. :param x0, y0: Optional. Initial guess at x and y locations. Default is center of the model. :param dx, dy: Optional. Distance in x and y to search from ``x0, y0``. Default is to search the entire model. :param plot: Optional. Plot results of the location. Default is false. """ # Load model print "Loading VM model..." vm = readVM(vmfile) # Setup search domain print "Setting up search domain..." if x0 is None: x0 = np.mean(vm.x) if y0 is None: y0 = np.mean(vm.y) if dx is None: xsearch = vm.x else: ix = vm.xrange2i(max(vm.r1[0], x0 - dx), min(vm.r2[0], x0 + dx)) xsearch = vm.x[ix] if dy is None: ysearch = vm.y else: iy = vm.yrange2i(max(vm.r1[1], y0 - dy), min(vm.r2[1], y0 + dy)) ysearch = vm.y[iy] # trace each point in the search region print "Building traveltime database for {:}x{:} search grid..."\ .format(len(xsearch), len(ysearch)) zz = vm.rf[iref] ipop = -1 population = [] db = PickDatabaseConnection(':memory:') for x in xsearch: for y in ysearch: z = zz[vm.x2i([x])[0], vm.y2i([y])[0]] ipop += 1 for _p in pickdb.get_picks(**pick_keys): p = dict(_p) p['ensemble'] = ipop p['receiver_x'] = x p['receiver_y'] = y p['receiver_z'] = z db.add_pick(**p) population.append((x, y, z)) print "Raytracing..." rayfile = '.locate.ray' raytrace(vmfile, db, rayfile, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) rays = readRayfanGroup(rayfile) imin = np.argmin([rfn.rms for rfn in rays.rayfans]) ipop = [rfn.start_point_id for rfn in rays.rayfans][imin] rms = [rfn.rms for rfn in rays.rayfans][imin] # # warn if fit point is on edge of search domain # if (vm.ny > 1) and ((yfit == ysearch[0]) or (yfit == ysearch[-1])): # on_edge = True # elif (xfit == xsearch[0]) or (xfit == xsearch[-1]): # on_edge = True # else: # on_edge = False # if on_edge: # msg = 'Best-fit location ({:},{:}) is on edge of model domain:'\ # .format(xfit, yfit) # msg += ' x=[{:},{:}], y=[{:},{:}].'.format(xsearch[0], xsearch[-1], # ysearch[0], ysearch[-1]) # msg += ' Try using a larger search region.' # warnings.warn(msg) # plot if plot: fig = plt.figure() ax = fig.add_subplot(111) if vm.ny == 1: ax.plot([p[0] for p in population], [rfn.rms for rfn in rays.rayfans], '.k') ax.plot(population[ipop][0], rms, '*r') plt.xlabel('x (km)') plt.ylabel('RMS error (s)') else: ax.plot([p[0] for p in population], [p[1] for p in population], '.k') ax.plot(population[ipop][0], population[ipop][1], '*r') ax.plot(x0, y0, 'og') plt.xlabel('x (km)') plt.xlabel('y (km)') plt.title('Results of locate_on_surface()') plt.show() return population[ipop][0], population[ipop][1], population[ipop][2], rms