Beispiel #1
0
 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')])
Beispiel #2
0
    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)
Beispiel #3
0
 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)])
Beispiel #4
0
 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)])
Beispiel #5
0
 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)
Beispiel #6
0
 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')])
Beispiel #7
0
    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)
Beispiel #8
0
 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)