def testLxnorm(self): """ expected results calculated by hand. """ yref = num.array([0., 1.5, 2.3, 0., -1.]) ytest = num.array([-1., 0.3, -0.3, 1., 0.2]) m, n = trace.Lx_norm(ytest, yref, norm=1) self.assertEqual(m, 7., 'L1-norm: m is not 7., but %s' % str(m)) self.assertEqual(n, 4.8, 'L1-norm: n is not 4.8, but %s' % str(n))
def misfit(tr_obs, tr_syn, taper, domain, exponent, tautoshift_max, autoshift_penalty_max, flip, result_mode='sparse', subtargets=[]): ''' Calculate misfit between observed and synthetic trace. :param tr_obs: observed trace as :py:class:`pyrocko.trace.Trace` :param tr_syn: synthetic trace as :py:class:`pyrocko.trace.Trace` :param taper: taper applied in timedomain as :py:class:`pyrocko.trace.Taper` :param domain: how to calculate difference, see :py:class:`DomainChoice` :param exponent: exponent of Lx type norms :param tautoshift_max: if non-zero, return lowest misfit when traces are allowed to shift against each other by up to +/- ``tautoshift_max`` :param autoshift_penalty_max: if non-zero, a penalty misfit is added for for non-zero shift values. The penalty value is ``autoshift_penalty_max * normalization_factor * \ tautoshift**2 / tautoshift_max**2`` :param flip: ``bool``, if set to ``True``, normalization factor is computed against *tr_syn* rather than *tr_obs* :param result_mode: ``'full'``, include traces and spectra or ``'sparse'``, include only misfit and normalization factor in result :returns: object of type :py:class:`WaveformMisfitResult` ''' trace.assert_same_sampling_rate(tr_obs, tr_syn) deltat = tr_obs.deltat tmin, tmax = taper.time_span() tr_proc_obs, trspec_proc_obs = _process(tr_obs, tmin, tmax, taper, domain) tr_proc_syn, trspec_proc_syn = _process(tr_syn, tmin, tmax, taper, domain) piggyback_results = [] for subtarget in subtargets: piggyback_results.append( subtarget.evaluate(tr_proc_obs, trspec_proc_obs, tr_proc_syn, trspec_proc_syn)) tshift = None ctr = None deltat = tr_proc_obs.deltat if domain in ('time_domain', 'envelope', 'absolute'): a, b = tr_proc_syn.ydata, tr_proc_obs.ydata if flip: b, a = a, b nshift_max = max( 0, min(a.size - 1, int(math.floor(tautoshift_max / deltat)))) if nshift_max == 0: m, n = trace.Lx_norm(a, b, norm=exponent) else: mns = [] for ishift in range(-nshift_max, nshift_max + 1): if ishift < 0: a_cut = a[-ishift:] b_cut = b[:ishift] elif ishift == 0: a_cut = a b_cut = b elif ishift > 0: a_cut = a[:-ishift] b_cut = b[ishift:] mns.append(trace.Lx_norm(a_cut, b_cut, norm=exponent)) ms, ns = num.array(mns).T iarg = num.argmin(ms) tshift = (iarg - nshift_max) * deltat m, n = ms[iarg], ns[iarg] m += autoshift_penalty_max * n * tshift**2 / tautoshift_max**2 elif domain == 'cc_max_norm': ctr = trace.correlate(tr_proc_syn, tr_proc_obs, mode='same', normalization='normal') tshift, cc_max = ctr.max() m = 0.5 - 0.5 * cc_max n = 0.5 elif domain == 'frequency_domain': a, b = trspec_proc_syn.ydata, trspec_proc_obs.ydata if flip: b, a = a, b m, n = trace.Lx_norm(num.abs(a), num.abs(b), norm=exponent) elif domain == 'log_frequency_domain': a, b = trspec_proc_syn.ydata, trspec_proc_obs.ydata if flip: b, a = a, b a = num.abs(a) b = num.abs(b) eps = (num.mean(a) + num.mean(b)) * 1e-7 if eps == 0.0: eps = 1e-7 a = num.log(a + eps) b = num.log(b + eps) m, n = trace.Lx_norm(a, b, norm=exponent) if result_mode == 'full': result = WaveformMisfitResult(misfits=num.array([[m, n]], dtype=num.float), processed_obs=tr_proc_obs, processed_syn=tr_proc_syn, filtered_obs=tr_obs.copy(), filtered_syn=tr_syn, spectrum_obs=trspec_proc_obs, spectrum_syn=trspec_proc_syn, taper=taper, tshift=tshift, cc=ctr) elif result_mode == 'sparse': result = WaveformMisfitResult( misfits=num.array([[m, n]], dtype=num.float)) else: assert False result.piggyback_subresults = piggyback_results return result
def testLxnorm(self): yref = num.array([0., 1.5, 2.3, 0., -1.]) ytest = num.array([-1., 0.3, -0.3, 1., 0.2]) m, n = trace.Lx_norm(ytest, yref, norm=1) self.assertEqual(m, 7., 'L1-norm: m is not 7., but %s' % str(m)) self.assertEqual(n, 4.8, 'L1-norm: n is not 4.8, but %s' % str(n))