def __init__(self, workdir, name='extension', failure_check=None): Step.__init__(self, workdir, name, failure_check=failure_check) self.params = ('rise_time',) self.required |= Step.outer_misfit_method_params | Step.inner_misfit_method_params \ | set([param+'_range' for param in self.params]) \ | set(self.params) self.optional |= set([d2u(p) for p in source_model.param_names('eikonal')])
def work(self, **kwargs): self.pre_work(True) seis = self.seismosizer conf = self.in_config.get_config() sourcetype = 'eikonal' base_source = source_model.Source( sourcetype ) for p in source_model.param_names(sourcetype): if d2u(p) in conf: base_source[p] = float(conf[d2u(p)]) seis.set_source(base_source) tapers_by_set = conf['taper'] tapers = [ tapers_by_set[i%len(tapers_by_set)] for i in range(len(seis.receivers)) ] seis.set_taper(tapers, base_source['depth']) if isinstance(conf['filter'], list): filters_by_set = conf['filter'] filters = [ filters_by_set[i%len(filters_by_set)] for i in range(len(seis.receivers)) ] seis.set_filters(filters) else: seis.set_filter(conf['filter']) shifts = seis.autoshift_ref_seismograms( conf['autoshift_range'] ) fails = [] limit = conf['autoshift_limit'] for i,s in enumerate(shifts): if s < limit[0] or limit[1] < s: seis.shift_ref_seismograms( [-s], [i+1] ) shifts[i] = 0. fails.append(True) else: fails.append(False) save = {} save['receivers'] = seis.receivers save['source_location'] = seis.source_location save['source'] = base_source save['shifts'] = shifts save['fails'] = fails self.dump(save, 'source_receivers') shifts_debug = [] for i,s in enumerate(shifts): trace = {} trace['name'] = seis.receivers[i].name trace['shift'] = s trace['failed'] = fails[i] shifts_debug.append(trace) self.out_config.shifts = shifts self.out_config.shifts_debug = shifts_debug self.post_work(True)
def __init__(self, workdir, sourcetype='eikonal', params=['time'], name=None, failure_check=None): if name is None: name = '-'.join(params)+'-greeper' Step.__init__(self, workdir, name, failure_check=failure_check) self.params = params self.sourcetype = sourcetype self.required |= Step.outer_misfit_method_params | Step.inner_misfit_method_params \ | set([param+'_range' for param in self.params]) \ | set(self.params) self.optional |= set([d2u(p) for p in source_model.param_names(sourcetype)])
def __init__(self, workdir, sourcetype='eikonal', params=['time'], name=None, xblacklist_level=None, dump_processing='filtered', ref_source_from=None, failure_check=None): if name is None: name = '-'.join(params)+'-tuner' Step.__init__(self, workdir, name, dump_processing, failure_check=failure_check) self.sourcetype = sourcetype self.params = params self.xblacklist_level = xblacklist_level self.ref_source_from = ref_source_from self.required |= Step.outer_misfit_method_params | Step.inner_misfit_method_params \ | set([param+'_range' for param in self.params]) \ | set(self.params) self.optional |= set([d2u(p) for p in source_model.param_names(self.sourcetype)])
def work(self, search=True, forward=True, run_id='current'): self.pre_work(search or forward) seis = self.seismosizer conf = self.in_config.get_config() mm_conf = self.in_config.get_config(keys=Step.outer_misfit_method_params) sourcetype = self.sourcetype base_source = source_model.Source( sourcetype ) for p in source_model.param_names(sourcetype): if d2u(p) in conf: base_source[p] = float(conf[d2u(p)]) if 'plane' in conf and conf['plane'] == 2: strike, dip, slip_rake = float(conf['strike']), float(conf['dip']), float(conf['slip_rake']) strike, dip, slip_rake = moment_tensor.other_plane( strike, dip, slip_rake ) base_source['strike'] = strike base_source['dip'] = dip base_source['slip-rake'] = slip_rake if 'plane' in conf: for param in 'strike', 'dip', 'slip-rake': self.out_config.__dict__['active_'+d2u(param)] = base_source[param] grid_def = [] for param in self.params: oldval = base_source[u2d(param)] descr = conf[param+'_range'] grid_def.append(grid_defi(u2d(param),oldval,descr)) if search or forward: self.setup_inner_misfit_method() if search: if self.ref_source_from is not None: step, ident = self.ref_source_from ref_source = step.get_snapshot_source(ident) else: ref_source = None self.setup_inner_misfit_method() finder = gridsearch.MisfitGrid( base_source, param_values=grid_def, ref_source=ref_source) finder.compute(seis) else: finder = self.load(self.stepname, run_id=run_id) finder.postprocess(**mm_conf) self.dump(finder, self.stepname) stats = finder.stats for param in self.params: str_result = stats[u2d(param)].str_best_and_confidence() logging.info(str_result) self.result(str_result, param ) base_source[u2d(param)] = stats[u2d(param)].best self.out_config.__dict__[param] = stats[u2d(param)].best self.out_config.__dict__[param+'_stats'] = stats[u2d(param)] self.out_config.min_misfit = finder.get_best_misfit() self.out_config.nstations_total = finder.nreceivers self.out_config.nstations_used = finder.nreceivers_enabled logging.info('Misfit = %f, Source = %s' % (finder.get_best_misfit(), str(base_source))) mt = base_source.moment_tensor() logging.info(str(mt)) self.result(str(mt), 'moment_tensor') misfit_median = finder.get_median_of_misfits_by_r() if self.xblacklist_level is not None: ir = 0 if 'xblacklist' in conf: xblacklist = set(conf['xblacklist']) else: xblacklist = set() for r, mm in zip(seis.receivers, finder.misfits_by_r): if mm/misfit_median > self.xblacklist_level: xblacklist.add(ir) logging.info('Blacklisting: %i, %s, %g' % (ir+1, r.name, mm/misfit_median)) ir += 1 self.out_config.xblacklist = sorted(list(xblacklist)) if forward: self.snapshot( base_source, 'best', mm_conf ) self.post_work(search or forward)
def __init__(self, workdir, name='shifter', failure_check=None): Step.__init__(self, workdir, name, failure_check=failure_check) self.required |= set(('taper', 'filter', 'autoshift_range', 'autoshift_limit')) self.optional |= set([d2u(p) for p in source_model.param_names('eikonal')])
def work(self, search=True, forward=True, run_id='current'): self.pre_work(search or forward) seis = self.seismosizer conf = self.in_config.get_config() mm_conf = self.in_config.get_config(keys=Step.outer_misfit_method_params) sourcetype = self.sourcetype base_source = source_model.Source( sourcetype ) for p in source_model.param_names(sourcetype): if d2u(p) in conf: base_source[p] = float(conf[d2u(p)]) if 'plane' in conf and conf['plane'] == 2: strike, dip, slip_rake = float(conf['strike']), float(conf['dip']), float(conf['slip_rake']) strike, dip, slip_rake = moment_tensor.other_plane( strike, dip, slip_rake ) base_source['strike'] = strike base_source['dip'] = dip base_source['slip-rake'] = slip_rake if 'plane' in conf: for param in 'strike', 'dip', 'slip-rake': self.out_config.__dict__['active_'+d2u(param)] = base_source[param] # setup grid of starting points for gradient se starter_grid_def = [] for param in self.params: if param+'_start_range' in conf: oldval = base_source[u2d(param)] descr = conf[param+'_start_range'] starter_grid_def.append( grid_defi(u2d(param),oldval,descr) ) if starter_grid_def: starter_sources = base_source.grid( starter_grid_def ) else: starter_sources = [ base_source ] grid_def = [] for param in self.params: oldval = base_source[u2d(param)] descr = conf[param+'_range'] grid_def.append(grid_defi(u2d(param),oldval,descr)) dparams = [ u2d(param) for param in self.params ] self.nminfunccalls = 0 norms = [ num.min(vals[1:]-vals[:-1]) for (param, vals) in grid_def ] bounds = [ (num.min(vals)/norm,num.max(vals)/norm) for ((param, vals),norm) in zip(grid_def, norms) ] if search or forward: self.setup_inner_misfit_method() def x_to_source(x): source = copy.deepcopy(base_source) for i,param in enumerate(self.params): source[u2d(param)] = x[i]*norms[i] return source def source_to_x(source): x = [] for param, norm in zip(self.params, norms): x.append(source[u2d(param)]/norm) return x def minfunc(x): self.nminfunccalls += 1 source = x_to_source(x) try: logging.debug('Evaluating source: %s', source.pretty_str(dparams) ) best, misfit = seis.best_source([source], **mm_conf) logging.debug('Misfit: %g' % misfit) except NoValidSources: logging.warn('Gradient search aborted at invalid source:' ) for str_param in current_base.pretty_str(dparams).splitlines(): logging.warn( str_param ) raise return misfit if search: self.setup_inner_misfit_method() # fix depth range by trying out different depths for iparam, (param, vals) in enumerate(grid_def): if param == 'depth': depth_sources = base_source.grid( [ (param,vals) ] ) dummy_source, dummy_misfit, failings = seis.best_source(depth_sources, return_failings=True, **mm_conf) ok = [] for isource, source in enumerate(depth_sources): if isource not in failings: ok.append(source['depth']) miok = min(ok) maok = max(ok) bounds[iparam] = ((miok+gridsearch.step_at(ok,miok)*0.3)/norms[iparam], (maok-gridsearch.step_at(ok,maok)*0.3)/norms[iparam]) # grid search over gradient searches min_misfit = None very_best_source = None ngood = 0 ntotal = 0 for starter_source in starter_sources: ntotal += 1 # look if starting source is valid current_base = copy.deepcopy(starter_source) try: current_base, misfit = seis.best_source([current_base], **mm_conf) except NoValidSources: logging.warn('Skipping invalid starting source:') for str_param in current_base.pretty_str(dparams).splitlines(): logging.warn( str_param ) continue if min_misfit == None: min_misfit = misfit very_best_source = current_base x0 = source_to_x(current_base) try: x, misfit, d = fmin_l_bfgs_b(minfunc, x0, approx_grad=True, bounds=bounds, epsilon=0.2, factr=1e10) except NoValidSources: continue current = x_to_source(x) if d['warnflag'] != 0: continue # restart gradient search at current minimum x0 = source_to_x(current) try: x, misfit, d = fmin_l_bfgs_b(minfunc, x0, approx_grad=True, bounds=bounds, epsilon=0.05, factr=1e7) except NoValidSources: continue current = x_to_source(x) if d['warnflag'] != 0: continue minkind = '' if misfit < min_misfit: logging.info('Found possible minimum: Misfit = %f' % misfit) for str_param in current.pretty_str(dparams).splitlines(): logging.info( str_param ) if 'strike' in self.params: mt = moment_tensor.MomentTensor(strike=current['strike'], dip=current['dip'], rake=current['slip-rake']) fps1, fps2 = mt.str_fault_planes().strip().splitlines() logging.info(fps1) logging.info(fps2) min_misfit = misfit very_best_source = current ngood += 1 if min_misfit is None: raise Exception('No valid starting points found') else: logging.error('Fixme: inversion.py') very_best_source_normalform = copy.deepcopy(very_best_source) if 'strike' in base_source.keys(): very_best_source_normalform.disambigue_sdr() for param, coords in grid_def: val = very_best_source[param] remark = '' if snap(val,coords)[0] in (0,len(coords)-1): remark = ' (?: at end of range)' str_result = '%s = %g%s' % (param.title(), val, remark) logging.info(str_result) self.result(str_result, d2u(param)) base_source[param] = very_best_source_normalform[param] self.out_config.__dict__[d2u(param)] = very_best_source_normalform[param] str_result = 'Misfit = %g' % min_misfit logging.info(str_result) self.result(str_result, 'Misfit') self.out_config.__dict__['min_misfit'] = min_misfit logging.info('Total number iterations in gradient searches: %i' % self.nminfunccalls) logging.info('Number of gradient searches tried: %i' % ntotal) logging.info('Number of successful gradient searches: %i' % ngood) self.out_config.__dict__['greeper_nminfunccalls'] = self.nminfunccalls self.out_config.__dict__['greeper_ntotal'] = ntotal self.out_config.__dict__['greeper_ngood'] = ngood if forward: self.snapshot( base_source, 'best', mm_conf ) self.post_work(search or forward)
def work(self, search=True, forward=True, run_id='current'): self.pre_work(search or forward) seis = self.seismosizer conf = self.in_config.get_config() mm_conf = self.in_config.get_config(keys=Step.outer_misfit_method_params) sourcetype = 'eikonal' base_source = source_model.Source( sourcetype, {} ) for p in source_model.param_names(sourcetype): if d2u(p) in conf: base_source[p] = float(conf[d2u(p)]) grid_def = [] for param in self.params: oldval = base_source[u2d(param)] descr = conf[param+'_range'] grid_def.append(grid_defi(u2d(param),oldval,descr)) if search or forward: self.setup_inner_misfit_method() if search: self.setup_inner_misfit_method() finder = gridsearch.MisfitGrid( base_source, param_values=grid_def ) finder.compute(seis) else: finder = self.load(self.stepname, run_id=run_id) finder.postprocess(**mm_conf) self.dump(finder, self.stepname) stats = finder.stats for param in self.params: altparam = param if param == 'rise_time': altparam = 'duration' str_result = stats[u2d(param)].str_best_and_confidence() logging.info(str_result) base_source[u2d(param)] = stats[u2d(param)].best logging.info('Reweighting') xweights = num.where(finder.misfits_by_r != 0., 1./finder.misfits_by_r, 0.) mm_conf_copy = copy.copy(mm_conf) mm_conf_copy['receiver_weights'] = xweights*mm_conf['receiver_weights'] finder.postprocess(**mm_conf_copy) self.dump(finder, self.stepname) stats = finder.stats for param in self.params: altparam = param if param == 'rise_time': altparam = 'duration' str_result = stats[u2d(param)].str_best_and_confidence() logging.info(str_result) self.result(str_result, altparam ) base_source[u2d(param)] = stats[u2d(param)].best self.out_config.__dict__[altparam] = stats[u2d(param)].best self.out_config.__dict__[altparam+'_stats'] = stats[u2d(param)] self.out_config.receiver_weights = mm_conf_copy['receiver_weights'] self.out_config.best_point_source = base_source if forward: self.snapshot( base_source, 'best', mm_conf ) self.post_work(search or forward)