def evaluate(self, x, mask=None, result_mode='full', targets=None, nthreads=0): source = self.get_source(x) engine = self.get_engine() self.set_target_parameter_values(x) if mask is not None and targets is not None: raise ValueError('Mask cannot be defined with targets set.') targets = targets if targets is not None else self.targets for target in targets: target.set_result_mode(result_mode) modelling_targets = [] t2m_map = {} for itarget, target in enumerate(targets): t2m_map[target] = target.prepare_modelling(engine, source, targets) if mask is None or mask[itarget]: modelling_targets.extend(t2m_map[target]) u2m_map = {} for imtarget, mtarget in enumerate(modelling_targets): if mtarget not in u2m_map: u2m_map[mtarget] = [] u2m_map[mtarget].append(imtarget) modelling_targets_unique = list(u2m_map.keys()) resp = engine.process(source, modelling_targets_unique, nthreads=nthreads) modelling_results_unique = list(resp.results_list[0]) modelling_results = [None] * len(modelling_targets) for mtarget, mresult in zip( modelling_targets_unique, modelling_results_unique): for itarget in u2m_map[mtarget]: modelling_results[itarget] = mresult imt = 0 results = [] for itarget, target in enumerate(targets): nmt_this = len(t2m_map[target]) if mask is None or mask[itarget]: result = target.finalize_modelling( engine, source, t2m_map[target], modelling_results[imt:imt+nmt_this]) imt += nmt_this else: result = gf.SeismosizerError( 'target was excluded from modelling') results.append(result) return results
def finalize_modelling(self, engine, source, modelling_targets, modelling_results): ds = self.get_dataset() try: imt = 0 amps = [] for measure in [self.measure_a, self.measure_b]: nmt_this = measure.get_nmodelling_targets() amp_obs, _ = measure.evaluate(engine, source, modelling_targets[imt:imt + nmt_this], dataset=ds) amp_syn, _ = measure.evaluate( engine, source, modelling_targets[imt:imt + nmt_this], trs=[ r.trace.pyrocko_trace() for r in modelling_results[imt:imt + nmt_this] ]) amps.append((amp_obs, amp_syn)) imt += nmt_this (a_obs, a_syn), (b_obs, b_syn) = amps eps = self.fit_log_ratio_waterlevel if self.fit_log_ratio: res_a = num.log(a_obs / (a_obs + b_obs) + eps) \ - num.log(a_syn / (a_syn + b_syn) + eps) else: res_a = a_obs / (a_obs + b_obs) - a_syn / (a_syn + b_syn) misfit = num.abs(res_a) norm = 1.0 result = PhaseRatioResult(misfits=num.array([[misfit, norm]], dtype=num.float), a_obs=a_obs, b_obs=b_obs, a_syn=a_syn, b_syn=b_syn) return result except dataset.NotFound as e: logger.debug(str(e)) return gf.SeismosizerError('no waveform data, %s' % str(e))
def post_process(self, engine, source, tr_syn): tr_syn = tr_syn.pyrocko_trace() nslc = self.codes config = self.misfit_config tmin_fit, tmax_fit, tfade, tfade_taper = \ self.get_taper_params(engine, source) ds = self.get_dataset() tobs, tsyn = self.get_pick_shift(engine, source) if None not in (tobs, tsyn): tobs_shift = tobs - tsyn else: tobs_shift = 0.0 tr_syn.extend(tmin_fit - tfade * 2.0, tmax_fit + tfade * 2.0, fillmethod='repeat') freqlimits = self.get_freqlimits() tr_syn = tr_syn.transfer(freqlimits=freqlimits, tfade=tfade) tr_syn.chop(tmin_fit - 2 * tfade, tmax_fit + 2 * tfade) tmin_obs, tmax_obs = self.get_cutout_timespan(tmin_fit + tobs_shift, tmax_fit + tobs_shift, tfade) try: tr_obs = ds.get_waveform( nslc, tinc_cache=1.0 / (config.fmin or 0.1 * config.fmax), tmin=tmin_fit + tobs_shift - tfade, tmax=tmax_fit + tobs_shift + tfade, tfade=tfade, freqlimits=freqlimits, deltat=tr_syn.deltat, cache=True, backazimuth=self.get_backazimuth_for_waveform()) if tobs_shift != 0.0: tr_obs = tr_obs.copy() tr_obs.shift(-tobs_shift) mr = misfit(tr_obs, tr_syn, taper=trace.CosTaper(tmin_fit - tfade_taper, tmin_fit, tmax_fit, tmax_fit + tfade_taper), domain=config.domain, exponent=config.norm_exponent, flip=self.flip_norm, result_mode=self._result_mode, tautoshift_max=config.tautoshift_max, autoshift_penalty_max=config.autoshift_penalty_max, subtargets=self._piggyback_subtargets) self._piggyback_subtargets = [] mr.tobs_shift = float(tobs_shift) mr.tsyn_pick = float_or_none(tsyn) return mr except NotFound as e: logger.debug(str(e)) raise gf.SeismosizerError('no waveform data, %s' % str(e))