Ejemplo n.º 1
0
 def get_transfer_function(self, codes):
     if self.seismogram_quantity == 'displacement':
         return None
     elif self.seismogram_quantity == 'velocity':
         return trace.DifferentiationResponse(1)
     elif self.seismogram_quantity == 'acceleration':
         return trace.DifferentiationResponse(2)
     elif self.seismogram_quantity == 'counts':
         raise NotImplemented()
Ejemplo n.º 2
0
    def test_dump_load(self):

        r = trace.FrequencyResponse()

        r = trace.PoleZeroResponse([0j, 0j], [1j, 2j, 1 + 3j, 1 - 3j], 1.0)
        r.regularize()
        r2 = guts.load_string(r.dump())
        assert cnumeq(r.poles, r2.poles, 1e-6)
        assert cnumeq(r.zeros, r2.zeros, 1e-6)
        assert numeq(r.constant, r2.constant)

        r = trace.SampledResponse([0., 1., 5., 10.], [0., 1., 1., 0.])

        r.regularize()
        r2 = guts.load_string(r.dump())
        assert numeq(r.frequencies, r2.frequencies, 1e-6)
        assert cnumeq(r.values, r2.values, 1e-6)

        r = trace.IntegrationResponse(2, 5.0)
        r2 = guts.load_string(r.dump())
        assert numeq(r.n, r2.n)
        assert numeq(r.gain, r2.gain, 1e-6)

        r = trace.DifferentiationResponse(2, 5.0)
        r2 = guts.load_string(r.dump())
        assert numeq(r.n, r2.n)
        assert numeq(r.gain, r2.gain, 1e-6)

        r = trace.AnalogFilterResponse(a=[1.0, 2.0, 3.0], b=[2.0, 3.0])
        r2 = guts.load_string(r.dump())
        assert numeq(r.a, r2.a, 1e-6)
        assert numeq(r.b, r2.b, 1e-6)
Ejemplo n.º 3
0
    def testIntegrationDifferentiation(self):

        tlen = 100.
        dt = 0.1
        n = int(tlen / dt)
        f = 0.5
        tfade = tlen / 10.

        xdata = num.arange(n) * dt
        ydata = num.sin(xdata * 2. * num.pi * f)
        a = trace.Trace(channel='A', deltat=dt, ydata=ydata)

        b = a.transfer(tfade, (0.0, 0.1, 2., 3.),
                       transfer_function=trace.IntegrationResponse())
        b.set_codes(channel='B')

        c = a.transfer(tfade, (0.0, 0.1, 2., 3.),
                       transfer_function=trace.DifferentiationResponse())
        c.set_codes(channel='C')

        eps = 0.001
        xdata = b.get_xdata()
        ydata = b.get_ydata()
        ydata_shouldbe = -num.cos(xdata * 2 * num.pi * f) / (2. * num.pi * f)
        assert num.amax(num.abs(ydata-ydata_shouldbe)) < eps, \
            'integration failed'

        xdata = c.get_xdata()
        ydata = c.get_ydata()
        ydata_shouldbe = num.cos(xdata * 2 * num.pi * f) * (2. * num.pi * f)
        assert num.amax(num.abs(ydata-ydata_shouldbe)) < eps, \
            'differentiation failed'
Ejemplo n.º 4
0
    def test_differentiation(self):
        dt = 0.1
        dur = 10.0
        n = int(round(dur / dt))

        t0 = 5.0

        tau = 0.25

        t = num.arange(n)*dt
        y = num.exp(-(t-t0)**2/tau**2)
        a = trace.Trace(location='A', deltat=dt, ydata=y)

        dydt = num.exp(-(t-t0)**2/tau**2) * -2.0 / tau**2 * (t-t0)
        b = trace.Trace(location='B', deltat=dt, ydata=dydt)

        c = a.transfer(
            transfer_function=trace.DifferentiationResponse(), demean=False)
        c.set_codes(location='C')

        d = a.differentiate(inplace=False, order=4)
        d.set_codes(location='D')

        e = a.differentiate(inplace=False, order=2)
        e.set_codes(location='E')

        bmax = b.absmax()[1]

        assert numeq(b.ydata, c.ydata, 0.0001*bmax)
        assert numeq(b.ydata, d.ydata, 0.03*bmax)
        assert numeq(b.ydata, e.ydata, 0.2*bmax)

        # trace.snuffle([a, b, c, d, e])

        c2 = c.transfer(
            transfer_function=trace.DifferentiationResponse(), demean=False)
        c2.set_codes(location='C2')

        c2max = c2.absmax()[1]

        d2 = a.differentiate(inplace=False, n=2, order=4)
        d2.set_codes(location='D2')
        e2 = a.differentiate(inplace=False, n=2, order=2)
        e2.set_codes(location='E2')

        assert numeq(c2.ydata, d2.ydata, 0.02*c2max)
        assert numeq(c2.ydata, e2.ydata, 0.1*c2max)
Ejemplo n.º 5
0
    def testIntegrationDifferentiation(self):

        fmin = 0.1
        fmax = 2.0
        for tlen in [100., 1000., 10000]:
            for dt in [0.1, 0.05]:
                for f in [0.2, 0.5, 1.0]:

                    n = int(tlen / dt)
                    tfade = 2.0 / fmin

                    xdata = num.arange(n) * dt
                    ydata = num.sin(xdata * 2. * num.pi * f)
                    a = trace.Trace(channel='A', deltat=dt, ydata=ydata)

                    b = a.transfer(
                        tfade, (fmin / 2., fmin, fmax, fmax * 2.),
                        transfer_function=trace.IntegrationResponse())
                    b.set_codes(channel='B')

                    c = a.transfer(
                        tfade, (fmin / 2., fmin, fmax, fmax * 2.),
                        transfer_function=trace.DifferentiationResponse())
                    c.set_codes(channel='C')

                    eps = 0.005
                    xdata = b.get_xdata()
                    ydata = b.get_ydata()
                    ydata_shouldbe = -num.cos(xdata * 2 * num.pi * f) / (
                        2. * num.pi * f)

                    # if num.amax(num.abs(ydata-ydata_shouldbe)) > eps:
                    # b_shouldbe = trace.Trace(
                    #     channel='B', location='integrated',
                    #     deltat=dt, ydata=ydata_shouldbe, tmin=xdata[0])
                    #     trace.snuffle([b, b_shouldbe])

                    assert num.amax(num.abs(ydata-ydata_shouldbe)) < eps, \
                        'integration failed'

                    xdata = c.get_xdata()
                    ydata = c.get_ydata()
                    ydata_shouldbe = num.cos(
                        xdata * 2 * num.pi * f) * (2. * num.pi * f)

                    # if num.amax(num.abs(ydata-ydata_shouldbe)) > eps:
                    # c_shouldbe = trace.Trace(
                    #     channel='C', location='differentiated',
                    #     deltat=dt, ydata=ydata_shouldbe, tmin=xdata[0])
                    #     trace.snuffle([c, c_shouldbe])

                    assert num.amax(num.abs(ydata-ydata_shouldbe)) < eps, \
                        'differentiation failed'
Ejemplo n.º 6
0
from pyrocko.guts import StringChoice, StringPattern, UnicodePattern, String,\
    Unicode, Int, Float, List, Object, Timestamp, ValidationError, TBase
from pyrocko.guts import load_xml  # noqa

from pyrocko import trace, model, util

guts_prefix = 'pf'

logger = logging.getLogger('pyrocko.fdsn.station')

conversion = {
    ('M', 'M'): None,
    ('M/S', 'M'): trace.IntegrationResponse(1),
    ('M/S**2', 'M'): trace.IntegrationResponse(2),
    ('M', 'M/S'): trace.DifferentiationResponse(1),
    ('M/S', 'M/S'): None,
    ('M/S**2', 'M/S'): trace.IntegrationResponse(1),
    ('M', 'M/S**2'): trace.DifferentiationResponse(2),
    ('M/S', 'M/S**2'): trace.DifferentiationResponse(1),
    ('M/S**2', 'M/S**2'): None
}


class NoResponseInformation(Exception):
    pass


class MultipleResponseInformation(Exception):
    pass
Ejemplo n.º 7
0
    def get_response(self, obj, quantity='displacement'):
        if (self.responses is None or len(self.responses) == 0) \
                and (self.responses_stationxml is None
                     or len(self.responses_stationxml) == 0):

            raise NotFound('No response information available.')

        quantity_to_unit = {
            'displacement': 'M',
            'velocity': 'M/S',
            'acceleration': 'M/S**2'
        }

        if self.is_blacklisted(obj):
            raise NotFound('Response is blacklisted:', self.get_nslc(obj))

        if not self.is_whitelisted(obj):
            raise NotFound('Response is not on whitelist:', self.get_nslc(obj))

        net, sta, loc, cha = self.get_nslc(obj)
        tmin, tmax = self.get_tmin_tmax(obj)

        keys_x = [(net, sta, loc, cha), (net, sta, '', cha),
                  ('', sta, '', cha)]

        keys = []
        for k in keys_x:
            if k not in keys:
                keys.append(k)

        candidates = []
        for k in keys:
            if k in self.responses:
                for x in self.responses[k]:
                    if x.tmin < tmin and (x.tmax is None or tmax < x.tmax):
                        if quantity == 'displacement':
                            candidates.append(x.response)
                        elif quantity == 'velocity':
                            candidates.append(
                                trace.MultiplyResponse([
                                    x.response,
                                    trace.DifferentiationResponse()
                                ]))
                        elif quantity == 'acceleration':
                            candidates.append(
                                trace.MultiplyResponse([
                                    x.response,
                                    trace.DifferentiationResponse(2)
                                ]))
                        else:
                            assert False

        for sx in self.responses_stationxml:
            try:
                candidates.append(
                    sx.get_pyrocko_response(
                        (net, sta, loc, cha),
                        timespan=(tmin, tmax),
                        fake_input_units=quantity_to_unit[quantity]))

            except (fs.NoResponseInformation, fs.MultipleResponseInformation):
                pass

        if len(candidates) == 1:
            return candidates[0]

        elif len(candidates) == 0:
            raise NotFound('No response found:', (net, sta, loc, cha))
        else:
            raise NotFound('Multiple responses found:', (net, sta, loc, cha))
Ejemplo n.º 8
0
    def evaluate(self,
                 engine,
                 source,
                 targets,
                 dataset=None,
                 trs=None,
                 extra_responses=[],
                 debug=False):

        from ..waveform import target as base

        trs_processed = []
        trs_orig = []
        for itarget, target in enumerate(targets):
            if target.codes[-1] not in self.channels:
                continue

            store = engine.get_store(target.store_id)

            tmin = source.time + store.t(self.timing_tmin, source, target)
            tmax = source.time + store.t(self.timing_tmax, source, target)

            if self.fmin is not None and self.fmax is not None:
                freqlimits = [
                    self.fmin / 2., self.fmin, self.fmax, self.fmax * 2.
                ]
                tfade = 1. / self.fmin

            else:
                freqlimits = None
                tfade = 0.0

            if dataset is not None:
                bazi = base.backazimuth_for_waveform(target.azimuth,
                                                     target.codes)

                tr = dataset.get_waveform(target.codes,
                                          tinc_cache=1.0 / self.fmin,
                                          quantity=self.quantity,
                                          tmin=tmin,
                                          tmax=tmax,
                                          freqlimits=freqlimits,
                                          tfade=tfade,
                                          deltat=store.config.deltat,
                                          cache=True,
                                          backazimuth=bazi)

            else:
                tr = trs[itarget]

                tr.extend(tmin - tfade, tmax + tfade, fillmethod='repeat')

                tr = tr.transfer(freqlimits=freqlimits, tfade=tfade)

            trs_orig.append(tr)

            tr = tr.copy()

            responses = []
            responses.extend(extra_responses)

            ndiff = \
                WaveformQuantity.choices.index(self.quantity) - \
                WaveformQuantity.choices.index(target.quantity)

            if ndiff > 0:
                responses.append(trace.DifferentiationResponse(ndiff))

            if ndiff < 0:
                responses.append(trace.IntegrationResponse(-ndiff))

            if self.response:
                responses.append(self.response)

            if self.named_response:
                responses.append(NamedResponse.map[self.named_response])

            if responses:
                trans = trace.MultiplyResponse(responses)
                try:
                    tr = tr.transfer(transfer_function=trans)

                except trace.TraceTooShort:
                    raise FeatureMeasurementFailed('transfer: trace too short')

            if tmin is None or tmax is None:
                raise FeatureMeasurementFailed(
                    'timing determination failed (phase unavailable?)')

            tr.chop(tmin, tmax)

            tr.set_location(tr.location + '-' + self.name + '-proc')
            trs_processed.append(tr)

        markers = []
        marker_candidates = []
        if self.method in ['peak_component', 'peak_to_peak_component']:
            component_amp_maxs = []
            for tr in trs_processed:
                y = tr.get_ydata()
                if self.method == 'peak_component':
                    yabs = num.abs(y)
                    i_at_amax = num.argmax(yabs)
                    amax = yabs[i_at_amax]
                    if debug:
                        t_at_amax = tr.tmin + i_at_amax * tr.deltat
                        mark = marker.Marker([tr.nslc_id], t_at_amax,
                                             t_at_amax, 0)

                        marker_candidates.append(mark)

                    component_amp_maxs.append(amax)
                else:
                    i_at_amax = num.argmax(y)
                    i_at_amin = num.argmin(y)
                    amax = y[i_at_amax]
                    amin = y[i_at_amin]
                    if debug:
                        t_at_amax = tr.tmin + i_at_amax * tr.deltat
                        t_at_amin = tr.tmin + i_at_amin * tr.deltat
                        ts = sorted([t_at_amax, t_at_amin])
                        mark = marker.Marker([tr.nslc_id], ts[0], ts[1], 0)

                        marker_candidates.append(mark)

                    component_amp_maxs.append(amax - amin)

            i_at_amax = num.argmax(component_amp_maxs)
            if debug:
                markers.append(marker_candidates[i_at_amax])
            amp_max = component_amp_maxs[i_at_amax]

        elif self.method == 'peak_absolute_vector':
            trsum = None
            for tr in trs_processed:
                tr.set_ydata(tr.get_ydata()**2)
                if trsum is None:
                    trsum = tr
                else:
                    trsum.add(tr)

            trsum.set_ydata(num.sqrt(tr.get_ydata))
            trsum.set_codes(channel='SUM')

            yabs = trsum.get_ydata()

            i_at_amax = num.argmax(yabs)
            amax = yabs[i_at_amax]
            t_at_amax = tr.tmin + i_at_amax * tr.deltat
            amp_max = amax

            if debug:
                markers.append(
                    marker.Marker([trsum.nslc_id], t_at_amax, t_at_amax, 0))

            trs_processed.append(trsum)

        elif self.method == 'spectral_average':
            component_amp_maxs = []
            for tr in trs_processed:
                freqs, values = tr.spectrum()
                component_amp_maxs.append(
                    num.mean(
                        num.abs(values[num.logical_and(self.fmin <= freqs,
                                                       freqs <= self.fmax)])))

            amp_max = num.mean(component_amp_maxs)

        if debug:
            trs_out = []
            for tr in trs_orig:
                tr_out = tr.copy()
                tr_out.set_location(tr_out.location + '-' + self.name)
                trs_out.append(tr_out)

            return amp_max, (trs_out + trs_processed, markers)

        return amp_max, None
Ejemplo n.º 9
0
    def test_pulse(self):
        store_dir = self.get_pulse_store_dir()

        engine = gf.LocalEngine(store_dirs=[store_dir])

        sources = [
            gf.ExplosionSource(
                time=0.0,
                depth=depth,
                moment=moment)

            for moment in (1.0, 2.0, 3.0) for depth in [100., 200., 300.]
        ]

        targets = [
            gf.Target(
                quantity=quantity,
                codes=('', 'STA', quantity, component),
                north_shift=500.,
                east_shift=0.)

            for component in 'ZNE'
            for quantity in ['displacement', 'velocity', 'acceleration']
        ]

        pulse = engine.get_store_extra(None, 'pulse')
        store = engine.get_store('pulse')

        response = engine.process(sources=sources, targets=targets)
        for source, target, tr in response.iter_results():
            t = tr.get_xdata()

            dist = math.sqrt((source.depth - target.depth)**2 +
                             source.distance_to(target)**2)

            data = pulse.evaluate(dist, t-source.time)

            phi = math.atan2((source.depth - target.depth),
                             source.distance_to(target)) * r2d

            azi, bazi = source.azibazi_to(target)

            data *= source.get_moment(store) * math.sqrt(2./3.)

            if tr.channel.endswith('N'):
                data *= math.cos(phi*d2r) * math.cos(azi*d2r)
            elif tr.channel.endswith('E'):
                data *= math.cos(phi*d2r) * math.sin(azi*d2r)
            elif tr.channel.endswith('Z'):
                data *= math.sin(phi*d2r)

            tr2 = tr.copy(data=False)
            tr2.set_ydata(data)
            tr2.set_codes(location='X')

            if target.quantity == 'velocity':
                tr2 = tr2.transfer(
                    transfer_function=trace.DifferentiationResponse(),
                    demean=False)

            elif target.quantity == 'acceleration':
                tr2 = tr2.transfer(
                    transfer_function=trace.DifferentiationResponse(2),
                    demean=False)

            # trace.snuffle([tr, tr2])

            amax = num.max(num.abs(tr.ydata))
            if amax > 1e-10:
                # print(num.max(num.abs(tr2.ydata - tr.ydata) / amax))
                assert num.all(num.abs(tr2.ydata - tr.ydata) < 0.05 * amax)
Ejemplo n.º 10
0
    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()

        if config.quantity == 'displacement':
            syn_resp = None
        elif config.quantity == 'velocity':
            syn_resp = trace.DifferentiationResponse(1)
        elif config.quantity == 'acceleration':
            syn_resp = trace.DifferentiationResponse(2)
        else:
            GrondError('Unsupported quantity: %s' % config.quantity)

        tr_syn = tr_syn.transfer(freqlimits=freqlimits,
                                 tfade=tfade,
                                 transfer_function=syn_resp)

        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,
                quantity=config.quantity,
                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))
Ejemplo n.º 11
0
def post_process(response,
                 norths,
                 easts,
                 stf_spec,
                 stations=False,
                 show=True,
                 savedir=None,
                 save=True,
                 quantity="velocity"):
    nnorth = norths.size
    neast = easts.size

    norths2, easts2 = coords_2d(norths, easts)

    by_i = defaultdict(list)
    traces = []
    for source, target, tr in response.iter_results():
        tr = tr.copy()

        if quantity == "velocity":
            trans = trace.DifferentiationResponse(1)
        if quantity == "acceleration":
            trans = trace.DifferentiationResponse(2)

        if quantity is not "displacement":
            trans = trace.MultiplyResponse([trans, stf_spec])

            tr = tr.transfer(transfer_function=trans)

        #tr.highpass(4, 0.5)
        #tr.lowpass(4, 4.0)
        tr_resamp = tr.copy()

        # uncomment to active resampling to get a smooth image (slow):
        tr_resamp.resample(tr.deltat * 0.25)
        by_i[int(target.codes[1])].append(tr_resamp)
        traces.append(tr)
    values = num.zeros(nnorth * neast)
    from pyrocko import trace as trd
    #    if stations is True:

    #        trd.snuffle(traces)
    #    if stations is True:
    #        from pyrocko import io
    #        io.save(traces, "traces_pgv.mseed")
    plot_trs = []
    for i in range(norths2.size):
        trs = by_i[i]
        if trs:
            ysum = num.sqrt(sum(tr.ydata**2 for tr in trs))
            ymax = num.max(ysum)
            values[i] = ymax
            if norths2[i] == easts2[i]:
                plot_trs.extend(trs)
    values = values.reshape((norths.size, easts.size))
    if save is True:
        path = savedir + '/shakemap.pkl'
        f = open(path, 'wb')
        pickle.dump([values, easts, norths], f)
        f.close()

    return values