Ejemplo n.º 1
0
 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))
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
 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))