def clip(self, path='', parameters=[], minval=-np.inf, maxval=np.inf): """ Clips kernels by convolving them with a Gaussian. Wrapper over xclip_sem utility. """ assert exists(path) assert len(parameters) > 0 unix.cd(self.getpath) for name in self.parameters: self.mpirun( PATH.SPECFEM_BIN +'/'+ 'xclip_sem ' + str(minval) + ' ' + str(maxval) + ' ' + name + '_kernel' + ' ' + path + '/ ' + path + '/ ') # move input files src = path dst = path + '_noclip' unix.mkdir(dst) for name in self.parameters: unix.mv(glob(src+'/*'+name+'.bin'), dst) # rename output files unix.rename('_clip', '', glob(src+'/*'))
def smooth(self, path='', parameters='dummy', span=0. ): """ Smooths SPECFEM2D kernels by convolving them with a Gaussian """ from seisflows.tools.array import meshsmooth, stack #assert parameters == self.parameters # implementing nproc > 1 would be straightforward, but a bit tedious #assert self.mesh.nproc == 1 kernels = self.load(path, suffix='_kernel') if not span: return kernels # set up grid _,x = loadbypar(PATH.MODEL_INIT, ['x'], 0) _,z = loadbypar(PATH.MODEL_INIT, ['z'], 0) mesh = stack(x[0], z[0]) for key in self.parameters: kernels[key] = [meshsmooth(kernels[key][0], mesh, span)] unix.rm(path + '_nosmooth') unix.mv(path, path + '_nosmooth') self.save(path, kernels, suffix='_kernel')
def export_kernels(self, path): unix.cd(self.kernel_databases) # work around conflicting name conventions files = [] files += glob('*proc??????_alpha_kernel.bin') files += glob('*proc??????_alpha[hv]_kernel.bin') files += glob('*proc??????_reg1_alpha_kernel.bin') files += glob('*proc??????_reg1_alpha[hv]_kernel.bin') unix.rename('alpha', 'vp', files) files = [] files += glob('*proc??????_beta_kernel.bin') files += glob('*proc??????_beta[hv]_kernel.bin') files += glob('*proc??????_reg1_beta_kernel.bin') files += glob('*proc??????_reg1_beta[hv]_kernel.bin') unix.rename('beta', 'vs', files) # hack to deal with problems on parallel filesystem unix.mkdir(join(path, 'kernels'), noexit=True) unix.mkdir(join(path, 'kernels', basename(self.getpath))) src = join(glob('*_kernel.bin')) dst = join(path, 'kernels', basename(self.getpath)) unix.mv(src, dst)
def export_residuals(self, path): # hack deals with problems on parallel filesystem unix.mkdir(join(path, 'residuals'), noexit=True) src = join(self.getpath, 'residuals') dst = join(path, 'residuals', basename(self.getpath)) unix.mv(src, dst)
def forward(self): """ Calls SPECFEM3D_GLOBE forward solver """ solvertools.setpar('SIMULATION_TYPE', '1') solvertools.setpar('SAVE_FORWARD', '.true.') self.mpirun('bin/xspecfem3D') unix.mv(self.data_wildcard, 'traces/syn')
def smooth(self, path='', parameters=[], span=0.): """ Smooths kernels by convolving them with a Gaussian. Wrapper over xsmooth_sem utility. """ assert exists(path) assert len(parameters) > 0 # apply smoothing operator unix.cd(self.getpath) for name in parameters: print ' smoothing', name self.mpirun( PATH.SPECFEM_BIN +'/'+ 'xsmooth_sem ' + str(span) + ' ' + str(span) + ' ' + name + '_kernel' + ' ' + path + '/ ' + path + '/ ', output=self.getpath+'/'+'OUTPUT_FILES/output_smooth_sem.txt') print '' # move input files src = path dst = path + '_nosmooth' unix.mkdir(dst) for name in self.parameters: unix.mv(glob(src+'/*'+name+'.bin'), dst) # rename output files unix.rename('_smooth', '', glob(src+'/*'))
def save(self, path, v, backup=None): if backup: src = path +'/'+ 'gradient' dst = path +'/'+ 'gradient_'+backup unix.mv(src, dst) solver.save(path +'/'+ 'gradient', solver.split(v), suffix='_kernel')
def export_kernels(self, path): unix.cd(self.kernel_databases) # work around conflicting name conventions self.rename_kernels() src = glob('*_kernel.bin') dst = join(path, 'kernels', self.source_name) unix.mkdir(dst) unix.mv(src, dst)
def clean(self): isready = self.solver_status() if isready: unix.rm(PATH.GRAD) unix.mv(PATH.FUNC, PATH.GRAD) unix.mkdir(PATH.FUNC) unix.rm(PATH.SOLVER) unix.mv(PATH.SOLVER+'_best', PATH.SOLVER) else: super(thrifty_inversion, self).clean()
def clean(self): # can forward simulations from line search be carried over? self.update_status() if self.status==1: unix.rm(PATH.GRAD) unix.mv(PATH.FUNC, PATH.GRAD) unix.mkdir(PATH.FUNC) else: super(thrifty_inversion, self).clean()
def iterate_search(self): super(thrifty_inversion, self).iterate_search() isdone = optimize.isdone isready = self.solver_status() # to avoid redundant forward simulation, save solver files associated # with 'best' trial model if isready and isdone: unix.rm(PATH.SOLVER+'_best') unix.mv(PATH.SOLVER, PATH.SOLVER+'_best')
def forward(self, path='traces/syn'): """ Calls SPECFEM3D_GLOBE forward solver """ solvertools.setpar('SIMULATION_TYPE', '1') solvertools.setpar('SAVE_FORWARD', '.true.') call_solver(system.mpiexec(), 'bin/xspecfem3D') if PAR.FORMAT in ['ASCII', 'ascii']: src = glob('OUTPUT_FILES/*.sem.ascii') dst = path unix.mv(src, dst)
def update_aggregate_gradient(self): """ Update stored aggregate gradient. """ names = self.check_source_names() subset = [names[isrc] for isrc in self._source_subset] print subset for source_name in subset: src = glob(join(PATH.GRAD, 'kernels', source_name, '*')) dst = join(PATH.GRAD_AGG, source_name) unix.mv(src, dst)
def forward(self, path='traces/syn'): """ Calls SPECFEM2D forward solver """ setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.true.') call_solver(system.mpiexec(), 'bin/xmeshfem2D') call_solver(system.mpiexec(), 'bin/xspecfem2D') if PAR.FORMAT in ['SU', 'su']: filenames = glob('OUTPUT_FILES/*.su') unix.mv(filenames, path)
def clean(self): """ Determine if forward simulation from line search can be carried over """ self.update_status() if self.status == 1: print 'THRIFTY CLEAN' unix.rm(PATH.GRAD) unix.mv(PATH.FUNC, PATH.GRAD) unix.mkdir(PATH.FUNC) else: super(thrifty_inversion_nz, self).clean()
def forward(self, path='traces/syn'): """ Calls SPECFEM3D forward solver """ setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.true.') call_solver(system.mpiexec(), 'bin/xgenerate_databases') call_solver(system.mpiexec(), 'bin/xspecfem3D') if PAR.FORMAT in ['SU', 'su']: src = glob('OUTPUT_FILES/*_d?_SU') dst = path unix.mv(src, dst)
def apply_hess(self, path='', hessian='Newton'): """ Evaluates action of Hessian on a given model vector. """ unix.cd(self.getpath) self.imprt(path, 'model') self.forward() unix.mv(self.wildcard, 'traces/lcg') preprocess.prepare_apply_hess(self.getpath) self.adjoint() self.export_kernels(path)
def generate_data(self, **model_kwargs): """ Generates data """ self.generate_mesh(**model_kwargs) unix.cd(self.getpath) setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.true.') self.call('bin/xspecfem3D') unix.mv(self.data_wildcard, 'traces/obs') self.export_traces(PATH.OUTPUT, 'traces/obs')
def generate_data(self, **model_kwargs): """ Generates data """ self.generate_mesh(**model_kwargs) unix.cd(self.getpath) setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.true.') self.mpirun('bin/xspecfem3D') unix.mv(self.data_wildcard, 'traces/obs') self.export_traces(PATH.OUTPUT, 'traces/obs')
def export_kernels(self, path): unix.cd(self.kernel_databases) # work around conflicting name conventions self.rename_kernels() # two-step command used to work around parallel filesystem issue unix.mkdir(join(path, 'kernels'), noexit=True) unix.mkdir(join(path, 'kernels', basename(self.getpath))) src = glob('*_kernel.bin') dst = join(path, 'kernels', basename(self.getpath)) unix.mv(src, dst)
def finalize_search(self): """ Cleans working directory and writes updated model """ unix.cd(PATH.OPTIMIZE) m = self.load('m_new') g = self.load('g_new') p = self.load('p_new') s = loadtxt('s_new') x = self.step_lens() f = self.func_vals() # clean working directory unix.rm('alpha') unix.rm('m_try') unix.rm('f_try') if self.iter > 1: unix.rm('m_old') unix.rm('f_old') unix.rm('g_old') unix.rm('p_old') unix.rm('s_old') unix.mv('m_new', 'm_old') unix.mv('f_new', 'f_old') unix.mv('g_new', 'g_old') unix.mv('p_new', 'p_old') unix.mv('s_new', 's_old') # write updated model alpha = x[f.argmin()] savetxt('alpha', alpha) self.save('m_new', m + alpha * p) savetxt('f_new', f.min()) # append latest statistics self.writer('factor', -self.dot(g, g)**-0.5 * (f[1] - f[0]) / (x[1] - x[0])) self.writer('gradient_norm_L1', np.linalg.norm(g, 1)) self.writer('gradient_norm_L2', np.linalg.norm(g, 2)) self.writer('misfit', f[0]) self.writer('restarted', self.restarted) self.writer('slope', (f[1] - f[0]) / (x[1] - x[0])) self.writer('step_count', self.step_count) self.writer('step_length', x[f.argmin()]) self.writer('theta', 180. * np.pi**-1 * angle(p, -g)) self.stepwriter.newline()
def export_kernels(self, path): unix.mkdir_gpfs(join(path, 'kernels')) unix.mkdir_gpfs(join(path, 'kernels', self.getname)) for name in self.kernel_map.values(): src = join(glob(self.databases + '/' + '*' + name + '.bin')) dst = join(path, 'kernels', self.getname) unix.mv(src, dst) try: name = 'rhop_kernel' src = join(glob(self.databases + '/' + '*' + name + '.bin')) dst = join(path, 'kernels', self.getname) unix.mv(src, dst) except: pass
def clip(self, path='', thresh=1.): """ Clips SPECFEM2D kernels """ parts = self.load(path) if thresh >= 1.: return parts for key in self.parameters: # scale to [-1,1] minval = parts[key][0].min() maxval = parts[key][0].max() np.clip(parts[key][0], thresh*minval, thresh*maxval, out=parts[key][0]) unix.mv(path, path + '_noclip') self.save(path, parts)
def apply_hess(self, path=''): """ Computes action of Hessian on a given model vector. """ # a gradient evaluation must have already been carried out unix.cd(self.getpath) unix.mkdir('traces/lcg') self.import_model(path) self.forward() unix.mv(self.data_wildcard, 'traces/lcg') preprocess.prepare_apply_hess(self.getpath) self.adjoint() self.export_kernels(path)
def eval_func(self, path='', export_traces=False): """ Evaluates misfit function by carrying out forward simulation and comparing observations and synthetics. """ unix.cd(self.getpath) self.import_model(path) self.forward() unix.mv(self.data_wildcard, 'traces/syn') preprocess.prepare_eval_grad(self.getpath) self.export_residuals(path) if export_traces: self.export_traces(path, prefix='traces/syn')
def generate_data(self, **model_kwargs): """ Generates data """ self.generate_mesh(**model_kwargs) unix.cd(self.getpath) setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.true.') call_solver(system.mpiexec(), 'bin/xspecfem3D') if PAR.FORMAT in ['SU', 'su']: src = glob('OUTPUT_FILES/*_d?_SU') dst = 'traces/obs' unix.mv(src, dst)
def finalize_search(self): """ Cleans working directory and writes updated model """ unix.cd(PATH.OPTIMIZE) m = self.load("m_new") g = self.load("g_new") p = self.load("p_new") s = loadtxt("s_new") x = self.step_lens() f = self.func_vals() # clean working directory unix.rm("alpha") unix.rm("m_try") unix.rm("f_try") if self.iter > 1: unix.rm("m_old") unix.rm("f_old") unix.rm("g_old") unix.rm("p_old") unix.rm("s_old") unix.mv("m_new", "m_old") unix.mv("f_new", "f_old") unix.mv("g_new", "g_old") unix.mv("p_new", "p_old") unix.mv("s_new", "s_old") # write updated model alpha = x[f.argmin()] savetxt("alpha", alpha) self.save("m_new", m + alpha * p) savetxt("f_new", f.min()) # append latest output self.writer("factor", -self.dot(g, g) ** -0.5 * (f[1] - f[0]) / (x[1] - x[0])) self.writer("gradient_norm_L1", np.linalg.norm(g, 1)) self.writer("gradient_norm_L2", np.linalg.norm(g, 2)) self.writer("misfit", f[0]) self.writer("restarted", self.restarted) self.writer("slope", (f[1] - f[0]) / (x[1] - x[0])) self.writer("step_count", self.step_count) self.writer("step_length", x[f.argmin()]) self.writer("theta", 180.0 * np.pi ** -1 * angle(p, -g)) self.stepwriter.newline()
def finalize_search(self): """ Cleans working directory and writes updated model """ unix.cd(PATH.OPTIMIZE) m = self.load('m_new') g = self.load('g_new') p = self.load('p_new') s = loadtxt('s_new') x = self.step_lens() f = self.func_vals() # clean working directory unix.rm('alpha') unix.rm('m_try') unix.rm('f_try') if self.iter > 1: unix.rm('m_old') unix.rm('f_old') unix.rm('g_old') unix.rm('p_old') unix.rm('s_old') unix.mv('m_new', 'm_old') unix.mv('f_new', 'f_old') unix.mv('g_new', 'g_old') unix.mv('p_new', 'p_old') unix.mv('s_new', 's_old') # write updated model alpha = x[f.argmin()] savetxt('alpha', alpha) self.save('m_new', m + alpha*p) savetxt('f_new', f.min()) # append latest statistics self.writer('factor', -self.dot(g,g)**-0.5 * (f[1]-f[0])/(x[1]-x[0])) self.writer('gradient_norm_L1', np.linalg.norm(g, 1)) self.writer('gradient_norm_L2', np.linalg.norm(g, 2)) self.writer('misfit', f[0]) self.writer('restarted', self.restarted) self.writer('slope', (f[1]-f[0])/(x[1]-x[0])) self.writer('step_count', self.step_count) self.writer('step_length', x[f.argmin()]) self.writer('theta', 180.*np.pi**-1*angle(p,-g)) self.stepwriter.newline()
def forward(self, path='traces/syn'): """ Calls SPECFEM2D forward solver """ setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.true.') call_solver(system.mpiexec(), 'bin/xmeshfem2D') call_solver(system.mpiexec(), 'bin/xspecfem2D') if PAR.FORMAT in ['SU', 'su']: filenames = glob('OUTPUT_FILES/*.su') # work around SPECFEM2D's different file names (depending on the # version used : unix.rename('single_p.su', 'single.su', filenames) filenames = glob('OUTPUT_FILES/*.su') unix.mv(filenames, path)
def clip(self, path='', tag='gradient', thresh=1.): """clips SPECFEM2D kernels""" parts = self.load(path + '/' + tag) if thresh >= 1.: return parts for key in self.inversion_parameters: # scale to [-1,1] minval = parts[key][0].min() maxval = parts[key][0].max() np.clip(parts[key][0], thresh * minval, thresh * maxval, out=parts[key][0]) unix.mv(path + '/' + tag, path + '/' + '_noclip') self.save(path + '/' + tag, parts)
def process_kernels(self, path, parameters): """ Processes kernels in accordance with parameter settings """ fullpath = path + '/' + 'kernels' assert exists(path) if exists(fullpath + '/' + 'sum'): unix.mv(fullpath + '/' + 'sum', fullpath + '/' + 'sum_nofix') # mask sources and receivers system.run('postprocess', 'fix_near_field', hosts='all', path=fullpath) system.run('solver', 'combine', hosts='head', path=fullpath, parameters=parameters)
def generate_data(self, **model_kwargs): """ Generates data """ self.generate_mesh(**model_kwargs) unix.cd(self.cwd) setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.true.') call_solver(system.mpiexec(), 'bin/xspecfem3D') if PAR.FORMAT in ['ASCII', 'ascii']: src = glob('OUTPUT_FILES/*.sem.ascii') dst = 'traces/obs' unix.mv(src, dst) if PAR.SAVETRACES: self.export_traces(PATH.OUTPUT+'/'+'traces/obs')
def search_status(self): """ Checks line search status """ if PAR.VERBOSE: print " trial step", optimize.step self.evaluate_function() isdone, isbest = optimize.search_status() if not PATH.LOCAL: if isbest and isdone: unix.rm(PATH.SOLVER + '_best') unix.mv(PATH.SOLVER, PATH.SOLVER + '_best') elif isbest: unix.rm(PATH.SOLVER + '_best') unix.cp(PATH.SOLVER, PATH.SOLVER + '_best') return isdone
def generate_data(self, **model_kwargs): """ Generates data """ self.generate_mesh(**model_kwargs) unix.cd(self.cwd) setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.true.') call_solver(system.mpiexec(), 'bin/xspecfem3D') if PAR.FORMAT in ['ASCII', 'ascii']: src = glob('OUTPUT_FILES/*.sem.ascii') dst = 'traces/obs' unix.mv(src, dst) if PAR.SAVETRACES: self.export_traces(PATH.OUTPUT + '/' + 'traces/obs')
def compute_precond(self, model_path=None, model_name=None, model_type='gll'): assert(model_name) assert(model_type) assert (exists(model_path)) unix.cd(solver.cwd) src = model_path dst = solver.model_databases solver.save(dst, solver.load(src)) solver.forward() unix.mv(solver.data_wildcard, 'traces/syn') solver.initialize_adjoint_traces('traces/syn') self.process_traces(solver.cwd) solver.adjoint() solver.export_kernels(PATH.GLOBAL)
def save(self, g, path='', parameters=[], backup=None): """ Utility for saving dictionary representation of gradient """ if not exists(path): raise Exception if not parameters: parameters = solver.parameters if backup: src = path +'/'+ 'gradient' dst = path +'/'+ 'gradient_'+backup unix.mv(src, dst) solver.save(solver.split(g), path +'/'+ 'gradient', parameters=parameters, suffix='_kernel')
def smooth(self, path='', span=0., parameters=[]): """ Smooths SPECFEM2D kernels by convolving them with a Gaussian """ from seisflows.tools.array import meshsmooth, stack kernels = self.load(path, suffix='_kernel') if not span: return kernels x = kernels['x'][0] z = kernels['z'][0] mesh = stack(x, z) for key in parameters: kernels[key] = [meshsmooth(kernels[key][0], mesh, span)] unix.mv(path, path + '_nosmooth') self.save(path, kernels)
def process_kernels(self, path, parameters): """ Processes kernels in accordance with parameter settings """ fullpath = path +'/'+ 'kernels' assert exists(path) if exists(fullpath +'/'+ 'sum'): unix.mv(fullpath +'/'+ 'sum', fullpath +'/'+ 'sum_nofix') # mask sources and receivers system.run('postprocess', 'fix_near_field', hosts='all', path=fullpath) system.run('solver', 'combine', hosts='head', path=fullpath, parameters=parameters)
def save(self, gradient, path='', parameters=[], backup=None): """ Convience function for saving dictionary representation of gradient """ if not exists(path): raise Exception if not parameters: parameters = solver.parameters if backup: src = path +'/'+ 'gradient' dst = path +'/'+ 'gradient_'+backup unix.mv(src, dst) solver.save(solver.split(gradient), path +'/'+ 'gradient', parameters=parameters, suffix='_kernel')
def write_gradient(self, path): super(mumford_shah, self).write_gradient(path) g = solver.load(path +'/'+ 'gradient', suffix='_kernel') m = solver.load(path +'/'+ 'model') mesh = self.getmesh() for parameter in solver.parameters: for iproc in range(PAR.NPROC): g[parameter][iproc] += PAR.GAMMA *\ sem.read(PATH.MUMFORD_SHAH_OUTPUT, parameter+'_dm', iproc) # save gradient self.save(path, solver.merge(g), backup='noregularize') # save edges src = PATH.MUMFORD_SHAH_OUTPUT dst = PATH.OUTPUT+'/'+'mumford_shah'+('_%04d' % optimize.iter) unix.mv(src, dst)
def generate_data(self, **model_kwargs): """ Generates data """ self.generate_mesh(**model_kwargs) unix.cd(self.cwd) setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.false.') call_solver(system.mpiexec(), 'bin/xmeshfem2D', output='mesher.log') call_solver(system.mpiexec(), 'bin/xspecfem2D') if PAR.FORMAT in ['SU', 'su']: src = glob('OUTPUT_FILES/*.su') dst = 'traces/obs' unix.mv(src, dst) if PAR.SAVETRACES: self.export_traces(PATH.OUTPUT + '/' + 'traces/obs')
def forward(self, path='traces/syn'): """ Calls SPECFEM3D forward solver and then moves files into path """ setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.true.') setpar('ATTENUATION ', '.true.') call_solver(system.mpiexec(), 'bin/xgenerate_databases') call_solver(system.mpiexec(), 'bin/xspecfem3D') # seismic unix output format if PAR.FORMAT in ['SU', 'su']: src = glob('OUTPUT_FILES/*_d?_SU') dst = path unix.mv(src, dst) # ascii sem output format elif PAR.FORMAT == "ascii": src = glob('OUTPUT_FILES/*sem?') dst = path unix.mv(src, dst)
def finalize_search(self): """ Prepares algorithm machinery and scratch directory for next model upate """ m = self.load('m_new') print("finalize_search") print(m) g = self.load('g_new') p = self.load('p_new') x = self.line_search.search_history()[0] f = self.line_search.search_history()[1] # clean scratch directory unix.cd(PATH.OPTIMIZE) if self.iter > 1: unix.rm('m_old') unix.rm('f_old') unix.rm('g_old') unix.rm('p_old') unix.rm('s_old') unix.mv('m_new', 'm_old') unix.mv('f_new', 'f_old') unix.mv('g_new', 'g_old') unix.mv('p_new', 'p_old') unix.mv('m_try', 'm_new') self.savetxt('f_new', f.min()) # output latest statistics self.writer('factor', -self.dot(g, g)**-0.5 * (f[1] - f[0]) / (x[1] - x[0])) self.writer('gradient_norm_L1', np.linalg.norm(g, 1)) self.writer('gradient_norm_L2', np.linalg.norm(g, 2)) self.writer('misfit', f[0]) self.writer('restarted', self.restarted) self.writer('slope', (f[1] - f[0]) / (x[1] - x[0])) self.writer('step_count', self.line_search.step_count) self.writer('step_length', x[f.argmin()]) self.writer('theta', 180. * np.pi**-1 * angle(p, -g)) self.line_search.writer.newline()
def smooth(self, path='', tag='gradient', span=0.): """smooths SPECFEM2D kernels by convolving them with a Gaussian""" from seisflows.tools.array import meshsmooth parts = self.load(path + '/' + tag) if not span: return parts # set up grid x = parts['x'][0] z = parts['z'][0] lx = x.max() - x.min() lz = z.max() - z.min() nn = x.size nx = np.around(np.sqrt(nn * lx / lz)) nz = np.around(np.sqrt(nn * lx / lz)) # perform smoothing for key in self.inversion_parameters: parts[key] = [meshsmooth(x, z, parts[key][0], span, nx, nz)] unix.mv(path + '/' + tag, path + '/' + '_nosmooth') self.save(path + '/' + tag, parts)
def clip(self, path='', parameters=[], minval=-np.inf, maxval=np.inf): """ Clips kernels by convolving them with a Gaussian. Wrapper over xclip_sem utility. """ assert exists(path) assert len(parameters) > 0 unix.cd(self.getpath) for name in self.parameters: self.call(PATH.SPECFEM_BIN + '/' + 'xclip_sem ' + str(minval) + ' ' + str(maxval) + ' ' + name + '_kernel' + ' ' + path + '/ ' + path + '/ ') # move input files src = path dst = path + '_noclip' unix.mkdir(dst) for name in self.parameters: unix.mv(glob(src + '/*' + name + '.bin'), dst) # rename output files unix.rename('_clip', '', glob(src + '/*'))
def smooth_legacy(path='', parameters=[], span=0.): solver = sys.modules['seisflows_solver'] PATH = sys.modules['seisflows_paths'] # intialize arrays kernels = {} for key in parameters or solver.parameters: kernels[key] = [] coords = {} for key in ['x', 'z']: coords[key] = [] # read kernels for key in parameters or solver.parameters: kernels[key] += solver.io.read_slice(path, key + '_kernel', 0) if not span: return kernels # read coordinates for key in ['x', 'z']: coords[key] += solver.io.read_slice(PATH.MODEL_INIT, key, 0) mesh = array.stack(coords['x'][0], coords['z'][0]) #mesh = array.stack(solver.mesh_properties.coords['x'][0], # solver.mesh_properties.coords['z'][0]) for key in parameters or solver.parameters: kernels[key] = [array.meshsmooth(kernels[key][0], mesh, span)] unix.rm(path + '_nosmooth') unix.mv(path, path + '_nosmooth') unix.mkdir(path) for key in parameters or solver.parameters: solver.io.write_slice(kernels[key][0], path, key + '_kernel', 0)
def finalize_search(self): """ Prepares algorithm machinery and scratch directory for next model upate """ m = self.load('m_new') g = self.load('g_new') p = self.load('p_new') x = self.line_search.search_history()[0] f = self.line_search.search_history()[1] # clean scratch directory unix.cd(PATH.OPTIMIZE) if self.iter > 1: unix.rm('m_old') unix.rm('f_old') unix.rm('g_old') unix.rm('p_old') unix.rm('s_old') unix.mv('m_new', 'm_old') unix.mv('f_new', 'f_old') unix.mv('g_new', 'g_old') unix.mv('p_new', 'p_old') unix.mv('m_try', 'm_new') self.savetxt('f_new', f.min()) # output latest statistics self.writer('factor', -self.dot(g,g)**-0.5 * (f[1]-f[0])/(x[1]-x[0])) self.writer('gradient_norm_L1', np.linalg.norm(g, 1)) self.writer('gradient_norm_L2', np.linalg.norm(g, 2)) self.writer('misfit', f[0]) self.writer('restarted', self.restarted) self.writer('slope', (f[1]-f[0])/(x[1]-x[0])) self.writer('step_count', self.line_search.step_count) self.writer('step_length', x[f.argmin()]) self.writer('theta', 180.*np.pi**-1*angle(p,-g)) self.line_search.writer.newline()
def generate_data(self, **model_kwargs): """ Generates data (perform meshing and database generation first) """ self.generate_mesh(**model_kwargs) unix.cd(self.cwd) setpar('SIMULATION_TYPE', '1') setpar('SAVE_FORWARD', '.false.') call_solver(system.mpiexec(), 'bin/xmeshfem2D', output='mesher.log') call_solver(system.mpiexec(), 'bin/xspecfem2D', output='solver.log') if PAR.FORMAT in ['SU', 'su']: src = glob('OUTPUT_FILES/*.su') # work around SPECFEM2D's different file names (depending on the # version used : unix.rename('single_p.su', 'single.su', src) src = glob('OUTPUT_FILES/*.su') dst = 'traces/obs' unix.mv(src, dst) if PAR.SAVETRACES: self.export_traces(PATH.OUTPUT + '/' + 'traces/obs')
def combine(self, path=''): """ combines SPECFEM3D_GLOBE kernels """ dirs = unix.ls(path) # initialize kernels unix.cd(path) for key in self.model_parameters: if key not in self.inversion_parameters: for i in range(PAR.NPROC): proc = '%06d' % i name = self.kernel_map[key] src = PATH.GLOBAL + '/' + 'mesh' + '/' + key + '/' + proc dst = path + '/' + 'sum' + '/' + 'proc' + proc + '_' + name + '.bin' savebin(np.load(src), dst) # create temporary files and directories unix.cd(self.getpath) with open('kernels_list.txt', 'w') as file: file.write('\n'.join(dirs) + '\n') unix.mkdir('INPUT_KERNELS') unix.mkdir('OUTPUT_SUM') for dir in dirs: src = path + '/' + dir dst = 'INPUT_KERNELS' + '/' + dir unix.ln(src, dst) # sum kernels self.mpirun(PATH.SOLVER_BINARIES + '/' + 'xsum_kernels') unix.mv('OUTPUT_SUM', path + '/' + 'sum') # remove temporary files and directories unix.rm('INPUT_KERNELS') unix.rm('kernels_list.txt') unix.cd(path)
def generate_precond(self, process_traces=None, model_path=None, model_name=None, model_type='gll'): assert(model_name) assert(model_type) assert (exists(model_path)) self.initialize_solver_directories() unix.cd(self.getpath) assert(exists(model_path)) self.check_mesh_properties(model_path) src = model_path dst = join(self.getpath, 'DATA/proc000000_rho_vp_vs.dat') unix.cp(src, dst) self.export_model(PATH.OUTPUT +'/'+ model_name) self.forward() unix.mv(self.data_wildcard, 'traces/syn') self.initialize_adjoint_traces('traces/syn') process_traces(self.getpath) self.adjoint() self.export_kernels(PATH.GLOBAL)
def smooth(self, path='', tag='gradient', span=0.): """ smooths SPECFEM3D_GLOBE kernels """ unix.cd(self.getpath) # list kernels kernels = [] for name in self.model_parameters: if name in self.inversion_parameters: flag = True else: flag = False region, name = name.split('_') kernels = kernels + [[name, flag]] # smooth kernels for name, flag in kernels: if flag: print ' smoothing', name self.mpirun(PATH.SOLVER_BINARIES + '/' + 'xsmooth_sem ' + str(span) + ' ' + str(span) + ' ' + name + ' ' + path + '/' + tag + '/ ' + self.databases + '/ ') # move kernels src = path + '/' + tag dst = path + '/' + '_nosmooth' unix.mkdir(dst) for name, flag in kernels: if flag: unix.mv(glob(src + '/*' + name + '.bin'), dst) else: unix.cp(glob(src + '/*' + name + '.bin'), dst) unix.rename('_smooth', '', glob(src + '/*')) print '' unix.cd(path)
def process_kernels(self, path, parameters): """ Processes kernels in accordance with parameter settings """ fullpath = path +'/'+ 'kernels' assert exists(path) if exists(fullpath +'/'+ 'sum'): unix.mv(fullpath +'/'+ 'sum', fullpath +'/'+ 'sum_nofix') print('==========in process_kernels, path==========') print(path) # mask sources and receivers system.run('postprocess', 'fix_near_field', #hosts='all', #path=fullpath) path=path) print('==========fix_near_field end1==========') system.run('solver', 'combine', #hosts='head', input_path=path, output_path=path+'/'+'sum', parameters=parameters) print('==========combine end==========')
def smooth(self, path='', parameters=None, span=0.): """ For a long time SPECFEM2D lacked its own smoothing utility; this method was intended only as a crude workaround """ from seisflows.tools import array assert self.mesh_properties.nproc == 1,\ msg.SmoothingError_SPECFEM2D kernels = self.load(path, suffix='_kernel') if not span: return kernels # set up grid x = sem.read(PATH.MODEL_INIT, 'x', 0) z = sem.read(PATH.MODEL_INIT, 'z', 0) mesh = array.stack(x, z) for key in parameters or self.parameters: kernels[key] = [array.meshsmooth(kernels[key][0], mesh, span)] unix.rm(path + '_nosmooth') unix.mv(path, path + '_nosmooth') self.save(path, kernels, suffix='_kernel')
def save_residuals(self): src = join(PATH.GRAD, 'residuals') dst = join(PATH.OUTPUT, 'residuals_%04d' % optimize.iter) unix.mv(src, dst)
def save_traces(self): src = join(PATH.GRAD, 'traces') dst = join(PATH.OUTPUT, 'traces_%04d' % optimize.iter) unix.mv(src, dst)
def save_gradient(self): src = join(PATH.GRAD, 'gradient') dst = join(PATH.OUTPUT, 'gradient_%04d' % optimize.iter) unix.mv(src, dst)